Merge "Notify ImsService Status Correctly"
diff --git a/Android.bp b/Android.bp
index 4f2e6d0..4ab5f1f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,7 @@
 }
 
 subdirs = [
+    "core/jni",
     "libs/*",
     "tools/*",
     "native/android",
diff --git a/Android.mk b/Android.mk
index c10a0cc..28abb89 100644
--- a/Android.mk
+++ b/Android.mk
@@ -332,7 +332,6 @@
 	core/java/android/service/chooser/IChooserTargetResult.aidl \
 	core/java/android/service/resolver/IResolverRankerService.aidl \
 	core/java/android/service/resolver/IResolverRankerResult.aidl \
-	core/java/android/text/ITextClassificationService.aidl \
 	core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\
 	core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
 	core/java/android/view/accessibility/IAccessibilityManager.aidl \
@@ -1091,6 +1090,7 @@
 		-showAnnotation android.annotation.SystemApi \
 		-api $(INTERNAL_PLATFORM_SYSTEM_API_FILE) \
 		-removedApi $(INTERNAL_PLATFORM_SYSTEM_REMOVED_API_FILE) \
+		-exactApi $(INTERNAL_PLATFORM_SYSTEM_EXACT_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
@@ -1127,6 +1127,7 @@
                -showAnnotation android.annotation.TestApi \
                -api $(INTERNAL_PLATFORM_TEST_API_FILE) \
                -removedApi $(INTERNAL_PLATFORM_TEST_REMOVED_API_FILE) \
+               -exactApi $(INTERNAL_PLATFORM_TEST_EXACT_API_FILE) \
                -nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
@@ -1280,8 +1281,6 @@
 include $(BUILD_DROIDDOC)
 
 # ==== docs for the web (on the androiddevdocs app engine server) =======================
-# TODO: Fix the System API docs build.
-ifneq ($(filter online-system-api-sdk-docs,$(MAKECMDGOALS)),)
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
@@ -1312,11 +1311,10 @@
 		-samplesdir $(samples_dir)
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
-# Don't build by default
+
 LOCAL_UNINSTALLABLE_MODULE := true
 
 include $(BUILD_DROIDDOC)
-endif  # online-system-api-sdk-docs in make command line.
 
 # ==== docs for the web (on the devsite app engine server) =======================
 include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index 0cb71a0..a25b334 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8059,8 +8059,8 @@
     method public boolean isScannable();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
-    field public static final int INTERVAL_HIGH = 160; // 0xa0
-    field public static final int INTERVAL_LOW = 1600; // 0x640
+    field public static final int INTERVAL_HIGH = 1600; // 0x640
+    field public static final int INTERVAL_LOW = 160; // 0xa0
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
diff --git a/api/system-current.txt b/api/system-current.txt
index 738ea33..b104542 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8539,8 +8539,8 @@
     method public boolean isScannable();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
-    field public static final int INTERVAL_HIGH = 160; // 0xa0
-    field public static final int INTERVAL_LOW = 1600; // 0x640
+    field public static final int INTERVAL_HIGH = 1600; // 0x640
+    field public static final int INTERVAL_LOW = 160; // 0xa0
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
diff --git a/api/test-current.txt b/api/test-current.txt
index a1850f5..84fe4c5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -8090,8 +8090,8 @@
     method public boolean isScannable();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
-    field public static final int INTERVAL_HIGH = 160; // 0xa0
-    field public static final int INTERVAL_LOW = 1600; // 0x640
+    field public static final int INTERVAL_HIGH = 1600; // 0x640
+    field public static final int INTERVAL_LOW = 160; // 0xa0
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index deb5b31..588a1bf 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1441,10 +1441,10 @@
             System.err.println("Error: no size specified");
             return showUsage();
         }
-        int len = size.length();
         long multiplier = 1;
-        if (len > 1) {
-            char c = size.charAt(len-1);
+        int len = size.length();
+        char c = size.charAt(len - 1);
+        if (c < '0' || c > '9') {
             if (c == 'K' || c == 'k') {
                 multiplier = 1024L;
             } else if (c == 'M' || c == 'm') {
diff --git a/cmds/uiautomator/instrumentation/Android.mk b/cmds/uiautomator/instrumentation/Android.mk
index 0c93b4c..e6cbdb4 100644
--- a/cmds/uiautomator/instrumentation/Android.mk
+++ b/cmds/uiautomator/instrumentation/Android.mk
@@ -22,6 +22,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, testrunner-src) \
     $(call all-java-files-under, ../library/core-src)
 LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
 LOCAL_MODULE := uiautomator-instrumentation
 # TODO: change this to 18 when it's available
 LOCAL_SDK_VERSION := current
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index a5b37f3..8fd8043 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -370,15 +370,6 @@
         "android.accounts.action.VISIBLE_ACCOUNTS_CHANGED";
 
     /**
-     * Key to set default visibility for applications targeting API level
-     * {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as
-     * authenticator See {@link #getAccountVisibility}. If the value was not set by authenticator
-     * {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used.
-     */
-    public static final String PACKAGE_NAME_KEY_LEGACY_VISIBLE =
-        "android:accounts:key_legacy_visible";
-
-    /**
      * Key to set visibility for applications which satisfy one of the following conditions:
      * <ul>
      * <li>Target API level below {@link android.os.Build.VERSION_CODES#O} and have
@@ -394,6 +385,14 @@
      * See {@link #getAccountVisibility}. If the value was not set by authenticator
      * {@link #VISIBILITY_USER_MANAGED_VISIBLE} is used.
      */
+    public static final String PACKAGE_NAME_KEY_LEGACY_VISIBLE =
+        "android:accounts:key_legacy_visible";
+
+    /**
+     * Key to set default visibility for applications which don't satisfy conditions in
+     * {@link PACKAGE_NAME_KEY_LEGACY_VISIBLE}. If the value was not set by authenticator
+     * {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used.
+     */
     public static final String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE =
             "android:accounts:key_legacy_not_visible";
 
@@ -608,14 +607,17 @@
     }
 
     /**
-     * Returns the accounts visible to the specified package, in an environment where some apps are
+     * Returns the accounts visible to the specified package in an environment where some apps are
      * not authorized to view all accounts. This method can only be called by system apps and
-     * authenticators managing the type
+     * authenticators managing the type.
+     * Beginning API level {@link android.os.Build.VERSION_CODES#O} it also return accounts
+     * which user can make visible to the application (see {@link VISIBILITY_USER_MANAGED_VISIBLE}).
      *
      * @param type The type of accounts to return, null to retrieve all accounts
      * @param packageName The package name of the app for which the accounts are to be returned
      * @return An array of {@link Account}, one per matching account. Empty (never null) if no
-     *         accounts of the specified type have been added.
+     *         accounts of the specified type can be accessed by the package.
+     *
      */
     @NonNull
     public Account[] getAccountsByTypeForPackage(String type, String packageName) {
@@ -644,7 +646,10 @@
      *
      * <p>
      * Caller targeting API level {@link android.os.Build.VERSION_CODES#O} and above, will get list
-     * of accounts made visible to it by user or AbstractAcccountAuthenticator and
+     * of accounts made visible to it by user
+     * (see {@link #newChooseAccountIntent(Account, List, String[], String,
+     * String, String[], Bundle)}) or AbstractAcccountAuthenticator
+     * using {@link setAccountVisibility}.
      * {@link android.Manifest.permission#GET_ACCOUNTS} permission is not used.
      *
      * <p>
@@ -787,7 +792,10 @@
      *
      * <p>
      * Caller targeting API level {@link android.os.Build.VERSION_CODES#O} and above, will get list
-     * of accounts made visible to it by user or AbstractAcccountAuthenticator and
+     * of accounts made visible to it by user
+     * (see {@link #newChooseAccountIntent(Account, List, String[], String,
+     * String, String[], Bundle)}) or AbstractAcccountAuthenticator
+     * using {@link setAccountVisibility}.
      * {@link android.Manifest.permission#GET_ACCOUNTS} permission is not used.
      *
      * <p>
@@ -869,7 +877,7 @@
     }
 
     /**
-     * Adds an account directly to the AccountManager. Additionally it specifies Account visiblity
+     * Adds an account directly to the AccountManager. Additionally it specifies Account visibility
      * for given list of packages.
      * <p>
      * Normally used by sign-up wizards associated with authenticators, not directly by
@@ -2663,8 +2671,8 @@
      *
      * <p>
      * This method gets a list of the accounts matching specific type and feature set which are
-     * visible to the caller or for which user can grant access (see {@link #getAccountsByType} for
-     * details); if there is exactly one already visible account, it is used; if there are some
+     * visible to the caller (see {@link #getAccountsByType} for details);
+     * if there is exactly one already visible account, it is used; if there are some
      * accounts for which user grant visibility, the user is prompted to pick one; if there are
      * none, the user is prompted to add one. Finally, an auth token is acquired for the chosen
      * account.
@@ -2735,6 +2743,9 @@
      * <p>
      * On success the activity returns a Bundle with the account name and type specified using
      * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
+     * Chosen account is marked as {@link #VISIBILITY_USER_MANAGED_VISIBLE} to the caller
+     * (see {@link setAccountVisibility}) and will be returned to it in consequent
+     * {@link #getAccountsByType}) calls.
      * <p>
      * The most common case is to call this with one account type, e.g.:
      * <p>
@@ -2787,6 +2798,9 @@
      * <p>
      * On success the activity returns a Bundle with the account name and type specified using
      * keys {@link #KEY_ACCOUNT_NAME} and {@link #KEY_ACCOUNT_TYPE}.
+     * Chosen account is marked as {@link #VISIBILITY_USER_MANAGED_VISIBLE} to the caller
+     * (see {@link setAccountVisibility}) and will be returned to it in consequent
+     * {@link #getAccountsByType}) calls.
      * <p>
      * The most common case is to call this with one account type, e.g.:
      * <p>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4f6c0c9..4dea0e0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -25,6 +25,7 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.DecorView;
 import com.android.internal.policy.PhoneWindow;
 
 import android.annotation.CallSuper;
@@ -130,6 +131,7 @@
 import java.util.HashMap;
 import java.util.List;
 
+import static android.os.Build.VERSION_CODES.O;
 import static java.lang.Character.MIN_VALUE;
 
 /**
@@ -973,6 +975,18 @@
     @CallSuper
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
+
+        if (getApplicationInfo().targetSdkVersion >= O && mActivityInfo.isFixedOrientation()) {
+            final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
+            final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
+            ta.recycle();
+
+            if (isTranslucentOrFloating) {
+                throw new IllegalStateException(
+                        "Only fullscreen opaque activities can request orientation");
+            }
+        }
+
         if (mLastNonConfigurationInstances != null) {
             mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
         }
@@ -3147,19 +3161,6 @@
     }
 
     /**
-     * Called before {@link #onAttachedToWindow}.
-     *
-     * @hide
-     */
-    @CallSuper
-    public void onBeforeAttachedToWindow() {
-        if (mAutoFillResetNeeded) {
-            getAutofillManager().onAttachedToWindow(
-                    getWindow().getDecorView().getRootView().getWindowToken());
-        }
-    }
-
-    /**
      * Called when the main window associated with the activity has been
      * attached to the window manager.
      * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
@@ -7273,7 +7274,7 @@
             }
         } else if (who.startsWith(AUTO_FILL_AUTH_WHO_PREFIX)) {
             Intent resultData = (resultCode == Activity.RESULT_OK) ? data : null;
-            getAutofillManager().onAuthenticationResult(resultData);
+            getAutofillManager().onAuthenticationResult(requestCode, resultData);
         } else {
             Fragment frag = mFragments.findFragmentByWho(who);
             if (frag != null) {
@@ -7418,10 +7419,11 @@
 
     /** @hide */
     @Override
-    final public void autofillCallbackAuthenticate(IntentSender intent, Intent fillInIntent) {
+    final public void autofillCallbackAuthenticate(int authenticationId, IntentSender intent,
+            Intent fillInIntent) {
         try {
             startIntentSenderForResultInner(intent, AUTO_FILL_AUTH_WHO_PREFIX,
-                    0, fillInIntent, 0, 0, null);
+                    authenticationId, fillInIntent, 0, 0, null);
         } catch (IntentSender.SendIntentException e) {
             Log.e(TAG, "authenticate() failed for intent:" + intent, e);
         }
@@ -7443,7 +7445,7 @@
         final int offsetX = (anchorBounds != null)
                 ? anchorBounds.left - actualAnchorBounds.left : 0;
         int offsetY = (anchorBounds != null)
-                ? anchorBounds.top - actualAnchorBounds.top : 0;
+                ? anchorBounds.bottom - actualAnchorBounds.bottom : 0;
 
         final boolean wasShowing;
 
@@ -7471,45 +7473,62 @@
     }
 
     /** @hide */
+    @NonNull public View[] findViewsByAccessibilityIdTraversal(@NonNull int[] viewIds) {
+        final View[] views = new View[viewIds.length];
+        final ArrayList<ViewRootImpl> roots =
+                WindowManagerGlobal.getInstance().getRootViews(getActivityToken());
+
+        for (int rootNum = 0; rootNum < roots.size(); rootNum++) {
+            final View rootView = roots.get(rootNum).getView();
+
+            if (rootView != null) {
+                for (int viewNum = 0; viewNum < viewIds.length; viewNum++) {
+                    if (views[viewNum] == null) {
+                        views[viewNum] = rootView.findViewByAccessibilityIdTraversal(
+                                viewIds[viewNum]);
+                    }
+                }
+            }
+        }
+
+        return views;
+    }
+
+    /** @hide */
     @Override
-    public boolean getViewVisibility(int viewId) {
-        Window window = getWindow();
-        if (window == null) {
-            Log.i(TAG, "no window");
-            return false;
-        }
+    @NonNull public boolean[] getViewVisibility(@NonNull int[] viewIds) {
+        final boolean[] isVisible = new boolean[viewIds.length];
+        final View views[] = findViewsByAccessibilityIdTraversal(viewIds);
 
-        View decorView = window.peekDecorView();
-        if (decorView == null) {
-            Log.i(TAG, "no decorView");
-            return false;
-        }
-
-        View view = decorView.findViewByAccessibilityIdTraversal(viewId);
-        if (view == null) {
-            Log.i(TAG, "cannot find view");
-            return false;
-        }
-
-        // Check if the view is visible by checking all parents
-        while (view != null) {
-            if (view == decorView) {
-                break;
+        for (int i = 0; i < viewIds.length; i++) {
+            View view = views[i];
+            if (view == null) {
+                isVisible[i] = false;
+                continue;
             }
 
-            if (view.getVisibility() != View.VISIBLE) {
-                Log.i(TAG, view + " is not visible");
-                return false;
-            }
+            isVisible[i] = true;
 
-            if (view.getParent() instanceof View) {
-                view = (View) view.getParent();
-            } else {
-                break;
+            // Check if the view is visible by checking all parents
+            while (true) {
+                if (view instanceof DecorView && view.getViewRootImpl() == view.getParent()) {
+                    break;
+                }
+
+                if (view.getVisibility() != View.VISIBLE) {
+                    isVisible[i] = false;
+                    break;
+                }
+
+                if (view.getParent() instanceof View) {
+                    view = (View) view.getParent();
+                } else {
+                    break;
+                }
             }
         }
 
-        return true;
+        return isVisible;
     }
 
     /** @hide */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index dd9db8a..928ef7e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4275,9 +4275,19 @@
             View.mDebugViewAttributes = debugViewAttributes;
 
             // request all activities to relaunch for the changes to take place
-            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
-                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
-                        false /* preserveWindow */);
+            requestRelaunchAllActivities();
+        }
+    }
+
+    private void requestRelaunchAllActivities() {
+        for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
+            final Activity activity = entry.getValue().activity;
+            if (!activity.mFinished) {
+                try {
+                    ActivityManager.getService().requestActivityRelaunch(entry.getKey());
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
             }
         }
     }
@@ -5084,24 +5094,26 @@
         // caused by other sources, such as overlays. That means we want to be as conservative
         // about code changes as possible. Take the diff of the old ApplicationInfo and the new
         // to see if anything needs to change.
+        LoadedApk apk;
+        LoadedApk resApk;
+        // Update all affected loaded packages with new package information
         synchronized (mResourcesManager) {
-            // Update all affected loaded packages with new package information
             WeakReference<LoadedApk> ref = mPackages.get(ai.packageName);
-            LoadedApk apk = ref != null ? ref.get() : null;
-            if (apk != null) {
-                final ArrayList<String> oldPaths = new ArrayList<>();
-                LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
-                apk.updateApplicationInfo(ai, oldPaths);
-            }
-
-            ref = mResourcePackages.get(ai.packageName);
             apk = ref != null ? ref.get() : null;
-            if (apk != null) {
-                final ArrayList<String> oldPaths = new ArrayList<>();
-                LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
-                apk.updateApplicationInfo(ai, oldPaths);
-            }
-
+            ref = mResourcePackages.get(ai.packageName);
+            resApk = ref != null ? ref.get() : null;
+        }
+        if (apk != null) {
+            final ArrayList<String> oldPaths = new ArrayList<>();
+            LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
+            apk.updateApplicationInfo(ai, oldPaths);
+        }
+        if (resApk != null) {
+            final ArrayList<String> oldPaths = new ArrayList<>();
+            LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
+            resApk.updateApplicationInfo(ai, oldPaths);
+        }
+        synchronized (mResourcesManager) {
             // Update all affected Resources objects to use new ResourcesImpl
             mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs);
         }
@@ -5116,14 +5128,7 @@
         newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1;
         handleConfigurationChanged(newConfig, null);
 
-        // Schedule all activities to reload
-        for (final Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
-            final Activity activity = entry.getValue().activity;
-            if (!activity.mFinished) {
-                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
-                        false);
-            }
-        }
+        requestRelaunchAllActivities();
     }
 
     static void freeTextLayoutCachesIfNeeded(int configDiff) {
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 21a7ca7..7d4d70d 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -570,8 +570,10 @@
             // Find the location in the view's parent
             ViewGroup parent = (ViewGroup) view.getParent();
             Matrix matrix = new Matrix();
-            parent.transformMatrixToLocal(matrix);
-            matrix.postTranslate(parent.getScrollX(), parent.getScrollY());
+            if (parent != null) {
+                parent.transformMatrixToLocal(matrix);
+                matrix.postTranslate(parent.getScrollX(), parent.getScrollY());
+            }
             mSharedElementParentMatrices.add(matrix);
         }
     }
@@ -861,15 +863,17 @@
             Matrix tempMatrix = new Matrix();
             for (int i = 0; i < numSharedElements; i++) {
                 View view = mSharedElements.get(i);
-                tempMatrix.reset();
-                mSharedElementParentMatrices.get(i).invert(tempMatrix);
-                GhostView.addGhost(view, decor, tempMatrix);
-                ViewGroup parent = (ViewGroup) view.getParent();
-                if (moveWithParent && !isInTransitionGroup(parent, decor)) {
-                    GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
-                    parent.getViewTreeObserver().addOnPreDrawListener(listener);
-                    parent.addOnAttachStateChangeListener(listener);
-                    mGhostViewListeners.add(listener);
+                if (view.isAttachedToWindow()) {
+                    tempMatrix.reset();
+                    mSharedElementParentMatrices.get(i).invert(tempMatrix);
+                    GhostView.addGhost(view, decor, tempMatrix);
+                    ViewGroup parent = (ViewGroup) view.getParent();
+                    if (moveWithParent && !isInTransitionGroup(parent, decor)) {
+                        GhostViewListeners listener = new GhostViewListeners(view, parent, decor);
+                        parent.getViewTreeObserver().addOnPreDrawListener(listener);
+                        parent.addOnAttachStateChangeListener(listener);
+                        mGhostViewListeners.add(listener);
+                    }
                 }
             }
         }
@@ -1065,7 +1069,7 @@
         @Override
         public boolean onPreDraw() {
             GhostView ghostView = GhostView.getGhost(mView);
-            if (ghostView == null) {
+            if (ghostView == null || !mView.isAttachedToWindow()) {
                 removeListener();
             } else {
                 GhostView.calculateMatrix(mView, mDecor, mMatrix);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 63c0ef3..1b2543c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2497,7 +2497,6 @@
             mBackStack = new ArrayList<BackStackRecord>();
         }
         mBackStack.add(state);
-        reportBackStackChanged();
     }
 
     boolean popBackStackState(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index aeccf56..68fce75 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -200,7 +200,7 @@
     void setRequestedOrientation(in IBinder token, int requestedOrientation);
     int getRequestedOrientation(in IBinder token);
     void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
-    void setProcessForeground(in IBinder token, int pid, boolean isForeground);
+    void setProcessImportant(in IBinder token, int pid, boolean isForeground, String reason);
     void setServiceForeground(in ComponentName className, in IBinder token,
             int id, in Notification notification, int flags);
     boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2e56bcf..0041879 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2675,6 +2675,7 @@
         private int mActionBarColor = COLOR_INVALID;
         private int mBackgroundColor = COLOR_INVALID;
         private int mForegroundColor = COLOR_INVALID;
+        private int mBackgroundColorHint = COLOR_INVALID;
 
         /**
          * Constructs a new Builder with the defaults:
@@ -3839,6 +3840,13 @@
                             backgroundColor);
                     mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mContext,
                             backgroundColor);
+                    if (backgroundColor != COLOR_DEFAULT
+                            && (mBackgroundColorHint != COLOR_INVALID || isColorized())) {
+                        mPrimaryTextColor = NotificationColorUtil.findAlphaToMeetContrast(
+                                mPrimaryTextColor, backgroundColor, 4.5);
+                        mSecondaryTextColor = NotificationColorUtil.findAlphaToMeetContrast(
+                                mSecondaryTextColor, backgroundColor, 4.5);
+                    }
                 } else {
                     double backLum = NotificationColorUtil.calculateLuminance(backgroundColor);
                     double textLum = NotificationColorUtil.calculateLuminance(mForegroundColor);
@@ -4662,10 +4670,26 @@
             if (mCachedContrastColorIsFor == mN.color && mCachedContrastColor != COLOR_INVALID) {
                 return mCachedContrastColor;
             }
-            final int contrasted = NotificationColorUtil.resolveContrastColor(mContext, mN.color);
 
+            int color;
+            int background = mBackgroundColorHint;
+            if (mBackgroundColorHint == COLOR_INVALID) {
+                background = mContext.getColor(
+                        com.android.internal.R.color.notification_material_background_color);
+            }
+            if (mN.color == COLOR_DEFAULT) {
+                ensureColors();
+                color = mSecondaryTextColor;
+            } else {
+                color = NotificationColorUtil.resolveContrastColor(mContext, mN.color,
+                        background);
+            }
+            if (Color.alpha(color) < 255) {
+                // alpha doesn't go well for color filters, so let's blend it manually
+                color = NotificationColorUtil.compositeColors(color, background);
+            }
             mCachedContrastColorIsFor = mN.color;
-            return mCachedContrastColor = contrasted;
+            return mCachedContrastColor = color;
         }
 
         int resolveAmbientColor() {
@@ -4882,7 +4906,8 @@
             if (isColorized()) {
                 return mBackgroundColor != COLOR_INVALID ? mBackgroundColor : mN.color;
             } else {
-                return COLOR_DEFAULT;
+                return mBackgroundColorHint != COLOR_INVALID ? mBackgroundColorHint
+                        : COLOR_DEFAULT;
             }
         }
 
@@ -4913,6 +4938,17 @@
             mTextColorsAreForBackground = COLOR_INVALID;
             ensureColors();
         }
+
+        /**
+         * Sets the background color for this notification to be a different one then the default.
+         * This is mainly used to calculate contrast and won't necessarily be applied to the
+         * background.
+         *
+         * @hide
+         */
+        public void setBackgroundColorHint(int backgroundColor) {
+            mBackgroundColorHint = backgroundColor;
+        }
     }
 
     /**
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 040b330..8014eca 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -6,8 +6,6 @@
 import android.os.RemoteException;
 import android.service.vr.IVrManager;
 
-import java.io.FileDescriptor;
-
 /**
  * Used to control aspects of a devices Virtual Reality (VR) capabilities.
  * <p>
@@ -63,32 +61,4 @@
             e.rethrowFromSystemServer();
         }
     }
-
-    /**
-     * Initiate connection for system controller data.
-     *
-     * @param fd Controller data file descriptor.
-     *
-     * {@hide}
-     */
-    public void connectController(FileDescriptor fd) {
-        try {
-            mService.connectController(fd);
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Sever connection for system controller data.
-     *
-     * {@hide}
-     */
-    public void disconnectController() {
-        try {
-            mService.disconnectController();
-        } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
-        }
-    }
 }
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index 28704e6..995d98a 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -71,11 +71,12 @@
     public static final int TYPE_INSTALL_WINDOWED = 2;
 
     /**
-     * Incoming system updates (except for security updates) will be blocked for 30 days, after
-     * which the policy will no longer be effective and the system will revert back to its normal
-     * behavior as if no policy were set.
-     * <b>Note:</b> security updates (e.g. monthly security patches) will <i>not</i> be affected by
-     * this policy.
+     * Incoming system updates (except for security updates) will be blocked for a maximum of 30
+     * days, after which the policy will no longer be effective and the system will revert back to
+     * its normal behavior as if no policy were set.
+     *
+     * <p><b>Note:</b> security updates (e.g. monthly security patches) may <i>not</i> be affected
+     * by this policy, depending on the policy set by the device manufacturer and carrier.
      *
      * <p>After this policy expires, resetting it to any policy other than
      * {@link #TYPE_INSTALL_AUTOMATIC} will produce no effect, as the 30-day maximum delay has
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 7261dfa..1994206 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -18,6 +18,7 @@
 import android.os.PooledStringWriter;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.service.autofill.FillContext;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -1103,6 +1104,9 @@
          * Returns the transformation that has been applied to this view, such as a translation
          * or scaling.  The returned Matrix object is owned by ViewNode; do not modify it.
          * Returns null if there is no transformation applied to the view.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public Matrix getTransformation() {
             return mMatrix;
@@ -1112,6 +1116,9 @@
          * Returns the visual elevation of the view, used for shadowing and other visual
          * characterstics, as set by {@link ViewStructure#setElevation
          * ViewStructure.setElevation(float)}.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public float getElevation() {
             return mElevation;
@@ -1121,6 +1128,9 @@
          * Returns the alpha transformation of the view, used to reduce the overall opacity
          * of the view's contents, as set by {@link ViewStructure#setAlpha
          * ViewStructure.setAlpha(float)}.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public float getAlpha() {
             return mAlpha;
@@ -1289,6 +1299,9 @@
 
         /**
          * If {@link #getText()} is non-null, this is where the current selection starts.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int getTextSelectionStart() {
             return mText != null ? mText.mTextSelectionStart : -1;
@@ -1298,6 +1311,9 @@
          * If {@link #getText()} is non-null, this is where the current selection starts.
          * If there is no selection, returns the same value as {@link #getTextSelectionStart()},
          * indicating the cursor position.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int getTextSelectionEnd() {
             return mText != null ? mText.mTextSelectionEnd : -1;
@@ -1319,6 +1335,9 @@
          * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned.
          * Note that the text may also contain style spans that modify the color of specific
          * parts of the text.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int getTextBackgroundColor() {
             return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED;
@@ -1329,6 +1348,9 @@
          * with it.
          * Note that the text may also contain style spans that modify the size of specific
          * parts of the text.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public float getTextSize() {
             return mText != null ? mText.mTextSize : 0;
@@ -1341,6 +1363,9 @@
          * {@link #TEXT_STYLE_UNDERLINE}.
          * Note that the text may also contain style spans that modify the style of specific
          * parts of the text.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int getTextStyle() {
             return mText != null ? mText.mTextStyle : 0;
@@ -1351,6 +1376,9 @@
          * in the array is a formatted line of text, and the value it contains is the offset
          * into the text string where that line starts.  May return null if there is no line
          * information.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int[] getTextLineCharOffsets() {
             return mText != null ? mText.mLineCharOffsets : null;
@@ -1361,6 +1389,9 @@
          * in the array is a formatted line of text, and the value it contains is the baseline
          * where that text appears in the view.  May return null if there is no line
          * information.
+         *
+         * <p>It's only relevant when the {@link AssistStructure} is used for Assist purposes,
+         * not for Autofill purposes.
          */
         public int[] getTextLineBaselines() {
             return mText != null ? mText.mLineBaselines : null;
diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl
index a10de45..6d65e3e 100644
--- a/core/java/android/app/trust/ITrustManager.aidl
+++ b/core/java/android/app/trust/ITrustManager.aidl
@@ -34,4 +34,6 @@
     boolean isDeviceLocked(int userId);
     boolean isDeviceSecure(int userId);
     boolean isTrustUsuallyManaged(int userId);
+    void unlockedByFingerprintForUser(int userId);
+    void clearAllFingerprints();
 }
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 06b0aacd..3c681f2 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -25,8 +25,6 @@
 import android.os.RemoteException;
 import android.util.ArrayMap;
 
-import com.android.internal.widget.LockPatternUtils;
-
 /**
  * See {@link com.android.server.trust.TrustManagerService}
  * @hide
@@ -184,6 +182,32 @@
         }
     }
 
+    /**
+     * Updates the trust state for the user due to the user unlocking via fingerprint.
+     * Should only be called if user authenticated via fingerprint and bouncer can be skipped.
+     * @param userId
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void unlockedByFingerprintForUser(int userId) {
+        try {
+            mService.unlockedByFingerprintForUser(userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears authenticated fingerprints for all users.
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+    public void clearAllFingerprints() {
+        try {
+            mService.clearAllFingerprints();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
diff --git a/core/java/android/app/usage/ExternalStorageStats.java b/core/java/android/app/usage/ExternalStorageStats.java
index 83ac779e..d7e570f 100644
--- a/core/java/android/app/usage/ExternalStorageStats.java
+++ b/core/java/android/app/usage/ExternalStorageStats.java
@@ -37,30 +37,46 @@
     /**
      * Return the total bytes used by all files in the shared/external storage
      * hosted on this volume.
+     * <p>
+     * This value only includes data which is isolated for each user on a
+     * multiuser device. Any OBB data shared between users is not accounted in
+     * this value.
      */
     public @BytesLong long getTotalBytes() {
         return totalBytes;
     }
 
     /**
-     * Return the total bytes used by audio files in the shared/external storage
-     * hosted on this volume.
+     * Return the total bytes used by all audio files in the shared/external
+     * storage hosted on this volume.
+     * <p>
+     * This value only includes data which is isolated for each user on a
+     * multiuser device. This value does not include any app files which are all
+     * accounted under {@link #getAppBytes()}.
      */
     public @BytesLong long getAudioBytes() {
         return audioBytes;
     }
 
     /**
-     * Return the total bytes used by video files in the shared/external storage
-     * hosted on this volume.
+     * Return the total bytes used by all video files in the shared/external
+     * storage hosted on this volume.
+     * <p>
+     * This value only includes data which is isolated for each user on a
+     * multiuser device. This value does not include any app files which are all
+     * accounted under {@link #getAppBytes()}.
      */
     public @BytesLong long getVideoBytes() {
         return videoBytes;
     }
 
     /**
-     * Return the total bytes used by image files in the shared/external storage
-     * hosted on this volume.
+     * Return the total bytes used by all image files in the shared/external
+     * storage hosted on this volume.
+     * <p>
+     * This value only includes data which is isolated for each user on a
+     * multiuser device. This value does not include any app files which are all
+     * accounted under {@link #getAppBytes()}.
      */
     public @BytesLong long getImageBytes() {
         return imageBytes;
@@ -72,6 +88,9 @@
      * <p>
      * This data is already accounted against individual apps as returned
      * through {@link StorageStats}.
+     * <p>
+     * This value only includes data which is isolated for each user on a
+     * multiuser device.
      */
     public @BytesLong long getAppBytes() {
         return appBytes;
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index e2d4f5b..dc5c7b6 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -43,10 +43,10 @@
 interface IBluetoothGatt {
     List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
 
-    void registerScanner(in IScannerCallback callback);
+    void registerScanner(in IScannerCallback callback, in WorkSource workSource);
     void unregisterScanner(in int scannerId);
     void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
-                   in WorkSource workSource, in List scanStorages, in String callingPackage);
+                   in List scanStorages, in String callingPackage);
     void startScanForIntent(in PendingIntent intent, in ScanSettings settings, in List<ScanFilter> filters,
                             in String callingPackage);
     void stopScanForIntent(in PendingIntent intent, in String callingPackage);
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index 71c4484..e9747d8 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -34,7 +34,7 @@
     * Advertise on low frequency, around every 1000ms. This is the default and
     * preferred advertising mode as it consumes the least power.
     */
-    public static final int INTERVAL_LOW = 1600;
+    public static final int INTERVAL_HIGH = 1600;
 
     /**
      * Advertise on medium frequency, around every 250ms. This is balanced
@@ -47,7 +47,7 @@
      * has the highest power consumption and should not be used for continuous
      * background advertising.
      */
-    public static final int INTERVAL_HIGH = 160;
+    public static final int INTERVAL_LOW = 160;
 
     /**
      * Minimum value for advertising interval.
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 5246513..f3f0ae5 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -360,7 +360,7 @@
                 // Scan stopped.
                 if (mScannerId == -1) return;
                 try {
-                    mBluetoothGatt.registerScanner(this);
+                    mBluetoothGatt.registerScanner(this, mWorkSource);
                     wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
                 } catch (InterruptedException | RemoteException e) {
                     Log.e(TAG, "application registeration exception", e);
@@ -424,7 +424,7 @@
                         } else {
                             mScannerId = scannerId;
                             mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
-                                    mWorkSource, mResultStorages,
+                                    mResultStorages,
                                     ActivityThread.currentOpPackageName());
                         }
                     } catch (RemoteException e) {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
index 8891d2e..cf8f08f 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -26,8 +26,8 @@
  */
 public final class PeriodicAdvertisingParameters implements Parcelable {
 
-    private static final int INTERVAL_MAX = 80;
-    private static final int INTERVAL_MIN = 65519;
+    private static final int INTERVAL_MIN = 80;
+    private static final int INTERVAL_MAX = 65519;
 
     private final boolean includeTxPower;
     private final int interval;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 08c7f18..61a7be5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2891,6 +2891,7 @@
             CLIPBOARD_SERVICE,
             INPUT_METHOD_SERVICE,
             TEXT_SERVICES_MANAGER_SERVICE,
+            TEXT_CLASSIFICATION_SERVICE,
             APPWIDGET_SERVICE,
             //@hide: VOICE_INTERACTION_MANAGER_SERVICE,
             //@hide: BACKUP_SERVICE,
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 5264cd7..e127ca3 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -952,4 +952,12 @@
     public Handler getMainThreadHandler() {
         return mBase.getMainThreadHandler();
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int getNextAccessibilityId() {
+        return mBase.getNextAccessibilityId();
+    }
 }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 587ab3b..9a01476 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Configuration.NativeConfig;
+import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
@@ -440,7 +441,6 @@
      * @hide
      */
     public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x400000;
-
     /**
      * @hide Bit in {@link #flags}: If set, this component will only be seen
      * by the system user.  Only works with broadcast receivers.  Set from the
@@ -978,12 +978,20 @@
      * Returns true if the activity's orientation is fixed.
      * @hide
      */
-    boolean isFixedOrientation() {
+    public boolean isFixedOrientation() {
         return isFixedOrientationLandscape() || isFixedOrientationPortrait()
                 || screenOrientation == SCREEN_ORIENTATION_LOCKED;
     }
 
     /**
+     * Returns true if the specified orientation is considered fixed.
+     * @hide
+     */
+    static public boolean isFixedOrientation(int orientation) {
+        return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation);
+    }
+
+    /**
      * Returns true if the activity's orientation is fixed to landscape.
      * @hide
      */
@@ -1162,6 +1170,25 @@
         dest.writeFloat(maxAspectRatio);
     }
 
+    /**
+     * Determines whether the {@link Activity} is considered translucent or floating.
+     * @hide
+     */
+    public static boolean isTranslucentOrFloating(TypedArray attributes) {
+        final boolean isTranslucent =
+                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
+                        false);
+        final boolean isSwipeToDismiss = !attributes.hasValue(
+                com.android.internal.R.styleable.Window_windowIsTranslucent)
+                && attributes.getBoolean(
+                        com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
+        final boolean isFloating =
+                attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
+                        false);
+
+        return isFloating || isTranslucent || isSwipeToDismiss;
+    }
+
     public static final Parcelable.Creator<ActivityInfo> CREATOR
             = new Parcelable.Creator<ActivityInfo>() {
         public ActivityInfo createFromParcel(Parcel source) {
diff --git a/core/java/android/content/pm/InstantAppResolveInfo.java b/core/java/android/content/pm/InstantAppResolveInfo.java
index 603192a..dcaf66e 100644
--- a/core/java/android/content/pm/InstantAppResolveInfo.java
+++ b/core/java/android/content/pm/InstantAppResolveInfo.java
@@ -47,7 +47,7 @@
     private final int mVersionCode;
 
     public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
-            @Nullable List<InstantAppIntentFilter> filters, int versionConde) {
+            @Nullable List<InstantAppIntentFilter> filters, int versionCode) {
         // validate arguments
         if ((packageName == null && (filters != null && filters.size() != 0))
                 || (packageName != null && (filters == null || filters.size() == 0))) {
@@ -61,7 +61,7 @@
             mFilters = null;
         }
         mPackageName = packageName;
-        mVersionCode = versionConde;
+        mVersionCode = versionCode;
     }
 
     public InstantAppResolveInfo(@NonNull String hostName, @Nullable String packageName,
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 07125e0..9a5482a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2272,6 +2272,14 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports Wi-Fi Passpoint.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: This is a device dedicated to showing UI
      * on a vehicle headunit. A headunit here is defined to be inside a
      * vehicle that may or may not be moving. A headunit uses either a
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 2b76ae2..d0c6397 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -23,7 +23,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
@@ -96,6 +95,9 @@
     public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9;
 
     /** @hide */
+    public static final int FLAG_RETURNED_BY_SERVICE = 1 << 10;
+
+    /** @hide */
     @IntDef(flag = true,
             value = {
             FLAG_DYNAMIC,
@@ -108,6 +110,7 @@
             FLAG_STRINGS_RESOLVED,
             FLAG_IMMUTABLE,
             FLAG_ADAPTIVE_BITMAP,
+            FLAG_RETURNED_BY_SERVICE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ShortcutFlags {}
@@ -1343,6 +1346,16 @@
         return (mFlags & flags) == flags;
     }
 
+    /** @hide */
+    public boolean isReturnedByServer() {
+        return hasFlags(FLAG_RETURNED_BY_SERVICE);
+    }
+
+    /** @hide */
+    public void setReturnedByServer() {
+        addFlags(FLAG_RETURNED_BY_SERVICE);
+    }
+
     /** Return whether a shortcut is dynamic. */
     public boolean isDynamic() {
         return hasFlags(FLAG_DYNAMIC);
@@ -1450,7 +1463,7 @@
 
     /**
      * Return whether a shortcut's icon is adaptive bitmap following design guideline
-     * defined in {@link AdaptiveIconDrawable}.
+     * defined in {@link android.graphics.drawable.AdaptiveIconDrawable}.
      *
      * @hide internal/unit tests only
      */
@@ -1776,6 +1789,9 @@
         if (hasStringResourcesResolved()) {
             sb.append("Sr");
         }
+        if (isReturnedByServer()) {
+            sb.append("V");
+        }
         sb.append("]");
 
         sb.append(", packageName=");
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index a7c09b5..e3e0cc5 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -618,6 +618,10 @@
     /**
      * Return all dynamic shortcuts from the caller app.
      *
+     * <p>This API is intended to be used for examining what shortcuts are currently published.
+     * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+     * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+     *
      * @throws IllegalStateException when the user is locked.
      */
     @NonNull
@@ -633,6 +637,10 @@
     /**
      * Return all static (manifest) shortcuts from the caller app.
      *
+     * <p>This API is intended to be used for examining what shortcuts are currently published.
+     * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+     * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+     *
      * @throws IllegalStateException when the user is locked.
      */
     @NonNull
@@ -697,6 +705,10 @@
     /**
      * Return all pinned shortcuts from the caller app.
      *
+     * <p>This API is intended to be used for examining what shortcuts are currently published.
+     * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+     * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+     *
      * @throws IllegalStateException when the user is locked.
      */
     @NonNull
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index b21ccf1..042eb87f 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -18,6 +18,7 @@
 import com.android.internal.R;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Typeface;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -36,8 +37,6 @@
  */
 public class FontResourcesParser {
     private static final String TAG = "FontResourcesParser";
-    private static final int NORMAL_WEIGHT = 400;
-    private static final int ITALIC = 1;
 
     // A class represents single entry of font-family in xml file.
     public interface FamilyResourceEntry {}
@@ -78,10 +77,10 @@
     public static final class FontFileResourceEntry {
         private final @NonNull String mFileName;
         private int mWeight;
-        private boolean mItalic;
+        private int mItalic;
         private int mResourceId;
 
-        public FontFileResourceEntry(@NonNull String fileName, int weight, boolean italic) {
+        public FontFileResourceEntry(@NonNull String fileName, int weight, int italic) {
             mFileName = fileName;
             mWeight = weight;
             mItalic = italic;
@@ -95,7 +94,7 @@
             return mWeight;
         }
 
-        public boolean isItalic() {
+        public int getItalic() {
             return mItalic;
         }
     }
@@ -200,8 +199,10 @@
             throws XmlPullParserException, IOException {
         AttributeSet attrs = Xml.asAttributeSet(parser);
         TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamilyFont);
-        int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight, NORMAL_WEIGHT);
-        boolean isItalic = ITALIC == array.getInt(R.styleable.FontFamilyFont_fontStyle, 0);
+        int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight,
+                Typeface.RESOLVE_BY_FONT_TABLE);
+        int italic = array.getInt(R.styleable.FontFamilyFont_fontStyle,
+                Typeface.RESOLVE_BY_FONT_TABLE);
         String filename = array.getString(R.styleable.FontFamilyFont_font);
         array.recycle();
         while (parser.next() != XmlPullParser.END_TAG) {
@@ -210,7 +211,7 @@
         if (filename == null) {
             return null;
         }
-        return new FontFileResourceEntry(filename, weight, isItalic);
+        return new FontFileResourceEntry(filename, weight, italic);
     }
 
     private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 211d54d..63eedf5 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -107,7 +107,8 @@
     /**
      * Create a request suitable for zero shutter lag still capture. This means
      * means maximizing image quality without compromising preview frame rate.
-     * AE/AWB/AF should be on auto mode.
+     * AE/AWB/AF should be on auto mode. This is intended for application-operated ZSL. For
+     * device-operated ZSL, use {@link CaptureRequest#CONTROL_ENABLE_ZSL} if available.
      * This template is guaranteed to be supported on camera devices that support the
      * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING PRIVATE_REPROCESSING}
      * capability or the
@@ -115,6 +116,7 @@
      * capability.
      *
      * @see #createCaptureRequest
+     * @see CaptureRequest#CONTROL_ENABLE_ZSL
      */
     public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5;
 
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 279d73d..c41fc02 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1669,6 +1669,7 @@
      * <code>false</code> if present.</p>
      * <p>For applications targeting SDK versions older than O, the value of enableZsl in all
      * capture templates is always <code>false</code> if present.</p>
+     * <p>For application-operated ZSL, use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG template.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index aedfc4b..6d80c20 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2174,6 +2174,7 @@
      * <code>false</code> if present.</p>
      * <p>For applications targeting SDK versions older than O, the value of enableZsl in all
      * capture templates is always <code>false</code> if present.</p>
+     * <p>For application-operated ZSL, use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG template.</p>
      * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      *
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 7947620..d61fb97 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -42,8 +42,8 @@
 import javax.crypto.Mac;
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
-import static android.Manifest.permission.USE_FINGERPRINT;
 import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.USE_FINGERPRINT;
 
 /**
  * A class that coordinates access to the fingerprint hardware.
@@ -910,6 +910,7 @@
             } else if (mAuthenticationCallback != null) {
                 mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
                         getErrorString(errMsgId, vendorCode));
+                mAuthenticationCallback = null;
             } else if (mRemovalCallback != null) {
                 mRemovalCallback.onRemovalError(mRemovalFingerprint, clientErrMsgId,
                         getErrorString(errMsgId, vendorCode));
@@ -930,12 +931,14 @@
                 final AuthenticationResult result =
                         new AuthenticationResult(mCryptoObject, fp, userId);
                 mAuthenticationCallback.onAuthenticationSucceeded(result);
+                mAuthenticationCallback = null;
             }
         }
 
         private void sendAuthenticatedFailed() {
             if (mAuthenticationCallback != null) {
-               mAuthenticationCallback.onAuthenticationFailed();
+                mAuthenticationCallback.onAuthenticationFailed();
+                mAuthenticationCallback = null;
             }
         }
 
diff --git a/core/java/android/hardware/radio/ITuner.aidl b/core/java/android/hardware/radio/ITuner.aidl
index e09720d..4e6a1e7 100644
--- a/core/java/android/hardware/radio/ITuner.aidl
+++ b/core/java/android/hardware/radio/ITuner.aidl
@@ -29,12 +29,33 @@
 
     RadioManager.BandConfig getConfiguration();
 
-    int getProgramInformation(out RadioManager.ProgramInfo[] infoOut);
-
     /**
      * @throws IllegalStateException if tuner was opened without audio
      */
     void setMuted(boolean mute);
 
     boolean isMuted();
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void step(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void scan(boolean directionDown, boolean skipSubChannel);
+
+    /**
+     * @throws IllegalArgumentException if invalid arguments are passed
+     * @throws IllegalStateException if called out of sequence
+     */
+    void tune(int channel, int subChannel);
+
+    /**
+     * @throws IllegalStateException if called out of sequence
+     */
+    void cancel();
+
+    RadioManager.ProgramInfo getProgramInformation();
 }
diff --git a/core/java/android/hardware/radio/ITunerCallback.aidl b/core/java/android/hardware/radio/ITunerCallback.aidl
index 8ea7491..b32c683 100644
--- a/core/java/android/hardware/radio/ITunerCallback.aidl
+++ b/core/java/android/hardware/radio/ITunerCallback.aidl
@@ -22,4 +22,5 @@
 oneway interface ITunerCallback {
     void onError(int status);
     void onConfigurationChanged(in RadioManager.BandConfig config);
+    void onProgramInfoChanged(in RadioManager.ProgramInfo info);
 }
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index 0dddf3b..bffca61 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -109,26 +109,61 @@
 
     @Override
     public int step(int direction, boolean skipSubChannel) {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            mTuner.step(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't step", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
     }
 
     @Override
     public int scan(int direction, boolean skipSubChannel) {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            mTuner.scan(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't scan", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
     }
 
     @Override
     public int tune(int channel, int subChannel) {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            mTuner.tune(channel, subChannel);
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Can't tune", e);
+            return RadioManager.STATUS_BAD_VALUE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
     }
 
     @Override
     public int cancel() {
-        // TODO(b/36863239): forward to mTuner
-        throw new RuntimeException("Not implemented");
+        try {
+            mTuner.cancel();
+        } catch (IllegalStateException e) {
+            Log.e(TAG, "Can't cancel", e);
+            return RadioManager.STATUS_INVALID_OPERATION;
+        } catch (RemoteException e) {
+            Log.e(TAG, "service died", e);
+            return RadioManager.STATUS_DEAD_OBJECT;
+        }
+        return RadioManager.STATUS_OK;
     }
 
     @Override
@@ -137,7 +172,8 @@
             throw new IllegalArgumentException("The argument must be an array of length 1");
         }
         try {
-            return mTuner.getProgramInformation(info);
+            info[0] = mTuner.getProgramInformation();
+            return RadioManager.STATUS_OK;
         } catch (RemoteException e) {
             Log.e(TAG, "service died", e);
             return RadioManager.STATUS_DEAD_OBJECT;
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index 8268e4d..ba85017 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -20,18 +20,11 @@
 import android.annotation.Nullable;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Implements the ITunerCallback interface by forwarding calls to RadioTuner.Callback.
  */
 class TunerCallbackAdapter extends ITunerCallback.Stub {
-    private static final String TAG = "radio.TunerCallbackAdapter";
-
     @NonNull private final RadioTuner.Callback mCallback;
     @NonNull private final Handler mHandler;
 
@@ -53,4 +46,9 @@
     public void onConfigurationChanged(RadioManager.BandConfig config) {
         mHandler.post(() -> mCallback.onConfigurationChanged(config));
     }
+
+    @Override
+    public void onProgramInfoChanged(RadioManager.ProgramInfo info) {
+        mHandler.post(() -> mCallback.onProgramInfoChanged(info));
+    }
 }
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index ad20ce5..160376b 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -341,7 +341,8 @@
               }
           }
         }
-        Slog.w(TAG, "No Enrollment application supports the given keyphrase/locale");
+        Slog.w(TAG, "No enrollment application supports the given keyphrase/locale: '"
+                + keyphrase + "'/" + locale);
         return null;
     }
 
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index b56437e..0b1569c 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -20,6 +20,7 @@
 import android.util.Log;
 
 import com.android.internal.os.RoSystemProperties;
+import com.android.org.conscrypt.Conscrypt;
 import com.android.org.conscrypt.OpenSSLContextImpl;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.SSLClientSessionCache;
@@ -212,7 +213,7 @@
     private SSLSocketFactory makeSocketFactory(
             KeyManager[] keyManagers, TrustManager[] trustManagers) {
         try {
-            OpenSSLContextImpl sslContext = OpenSSLContextImpl.getPreferred();
+            OpenSSLContextImpl sslContext =  (OpenSSLContextImpl) Conscrypt.newPreferredSSLContextSpi();
             sslContext.engineInit(keyManagers, trustManagers, null);
             sslContext.engineGetClientSessionContext().setPersistentCache(mSessionCache);
             return sslContext.engineGetSocketFactory();
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 235f24c..b5fd116 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -183,8 +183,10 @@
      *   - Wakelock data (wl) gets current and max times.
      * New in version 20:
      *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
+     * New in version 21:
+     *   - Actual (not just apportioned) Wakelock time is also recorded.
      */
-    static final String CHECKIN_VERSION = "20";
+    static final String CHECKIN_VERSION = "21";
 
     /**
      * Old version, we hit 9 and ran out of room, need to remove.
@@ -194,7 +196,7 @@
     private static final long BYTES_PER_KB = 1024;
     private static final long BYTES_PER_MB = 1048576; // 1024^2
     private static final long BYTES_PER_GB = 1073741824; //1024^3
-    
+
     private static final String VERSION_DATA = "vers";
     private static final String UID_DATA = "uid";
     private static final String WAKEUP_ALARM_DATA = "wua";
@@ -205,6 +207,12 @@
     private static final String VIBRATOR_DATA = "vib";
     private static final String FOREGROUND_DATA = "fg";
     private static final String STATE_TIME_DATA = "st";
+    // wl line is:
+    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
+    // full totalTime,    'f', count, current duration, max duration, total duration,
+    // partial totalTime, 'p', count, current duration, max duration, total duration,
+    // window totalTime,  'w', count, current duration, max duration, total duration
+    // [Currently, full and window wakelocks have durations current = max = total = -1]
     private static final String WAKELOCK_DATA = "wl";
     private static final String SYNC_DATA = "sy";
     private static final String JOB_DATA = "jb";
@@ -513,6 +521,7 @@
         public abstract Timer getForegroundActivityTimer();
         public abstract Timer getBluetoothScanTimer();
         public abstract Timer getBluetoothScanBackgroundTimer();
+        public abstract Counter getBluetoothScanResultCounter();
 
         // Note: the following times are disjoint.  They can be added together to find the
         // total time a uid has had any processes running at all.
@@ -2659,6 +2668,12 @@
                     sb.append(" max=");
                     sb.append(maxDurationMs);
                 }
+                // Put actual time if it is available and different from totalTimeMillis.
+                final long totalDurMs = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
+                if (totalDurMs > totalTimeMillis) {
+                    sb.append(" actual=");
+                    sb.append(totalDurMs);
+                }
                 if (timer.isRunningLocked()) {
                     final long currentMs = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
                     if (currentMs >= 0) {
@@ -2742,13 +2757,15 @@
             long elapsedRealtimeUs, String name, int which, String linePrefix) {
         long totalTimeMicros = 0;
         int count = 0;
-        long max = -1;
-        long current = -1;
+        long max = 0;
+        long current = 0;
+        long totalDuration = 0;
         if (timer != null) {
             totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
-            count = timer.getCountLocked(which); 
+            count = timer.getCountLocked(which);
             current = timer.getCurrentDurationMsLocked(elapsedRealtimeUs/1000);
             max = timer.getMaxDurationMsLocked(elapsedRealtimeUs/1000);
+            totalDuration = timer.getTotalDurationMsLocked(elapsedRealtimeUs/1000);
         }
         sb.append(linePrefix);
         sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
@@ -2759,9 +2776,16 @@
         sb.append(current);
         sb.append(',');
         sb.append(max);
+        // Partial, full, and window wakelocks are pooled, so totalDuration is meaningful (albeit
+        // not always tracked). Kernel wakelocks (which have name == null) have no notion of
+        // totalDuration independent of totalTimeMicros (since they are not pooled).
+        if (name != null) {
+            sb.append(',');
+            sb.append(totalDuration);
+        }
         return ",";
     }
-    
+
     private static final void dumpLineHeader(PrintWriter pw, int uid, String category,
                                              String type) {
         pw.print(BATTERY_STATS_CHECKIN_VERSION);
@@ -3347,8 +3371,10 @@
                     final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeBg = bleTimerBg != null ?
                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
+                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
                     dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
-                            countBg, actualTime, actualTimeBg);
+                            countBg, actualTime, actualTimeBg, resultCount);
                 }
             }
 
@@ -4500,6 +4526,8 @@
                     final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                     final long actualTimeMsBg = bleTimerBg != null ?
                             bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
+                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
 
                     sb.setLength(0);
                     sb.append(prefix);
@@ -4524,6 +4552,8 @@
                         sb.append(countBg);
                         sb.append(" times)");
                     }
+                    sb.append("; Results count ");
+                    sb.append(resultCount);
                     pw.println(sb.toString());
                     uidActivity = true;
                 }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index eceaa31..6aa601a 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -189,10 +189,11 @@
             if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
                 throw new IllegalArgumentException(
                         "amplitude must either be DEFAULT_AMPLITUDE, " +
-                        "or between 1 and 255 inclusive");
+                        "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")");
             }
             if (mTiming <= 0) {
-                throw new IllegalArgumentException("timing must be positive");
+                throw new IllegalArgumentException(
+                        "timing must be positive (timing=" + mTiming + ")");
             }
         }
 
@@ -274,24 +275,31 @@
         public void validate() {
             if (mTimings.length != mAmplitudes.length) {
                 throw new IllegalArgumentException(
-                        "timing and amplitude arrays must be of equal length");
+                        "timing and amplitude arrays must be of equal length" +
+                        " (timings.length=" + mTimings.length +
+                        ", amplitudes.length=" + mAmplitudes.length + ")");
             }
             if (!hasNonZeroEntry(mTimings)) {
-                throw new IllegalArgumentException("at least one timing must be non-zero");
+                throw new IllegalArgumentException("at least one timing must be non-zero" +
+                        " (timings=" + Arrays.toString(mTimings) + ")");
             }
             for (long timing : mTimings) {
                 if (timing < 0) {
-                    throw new IllegalArgumentException("timings must all be >= 0");
+                    throw new IllegalArgumentException("timings must all be >= 0" +
+                            " (timings=" + Arrays.toString(mTimings) + ")");
                 }
             }
             for (int amplitude : mAmplitudes) {
                 if (amplitude < -1 || amplitude > 255) {
                     throw new IllegalArgumentException(
-                            "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255");
+                            "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255" +
+                            " (amplitudes=" + Arrays.toString(mAmplitudes) + ")");
                 }
             }
             if (mRepeat < -1 || mRepeat >= mTimings.length) {
-                throw new IllegalArgumentException("repeat index must be >= -1");
+                throw new IllegalArgumentException(
+                        "repeat index must be within the bounds of the timings array" +
+                        " (timings.length=" + mTimings.length + ", index=" + mRepeat +")");
             }
         }
 
@@ -375,7 +383,8 @@
         @Override
         public void validate() {
             if (mEffectId != EFFECT_CLICK) {
-                throw new IllegalArgumentException("Unknown prebaked effect type");
+                throw new IllegalArgumentException(
+                        "Unknown prebaked effect type (value=" + mEffectId + ")");
             }
         }
 
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 1e55c78..2f0eeca 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -157,6 +157,8 @@
         // This call needs to continue throwing ArrayIndexOutOfBoundsException but ignore all other
         // exceptions for compatibility purposes
         if (repeat < -1 || repeat >= pattern.length) {
+            Log.e(TAG, "vibrate called with repeat index out of bounds" +
+                    " (pattern.length=" + pattern.length + ", index=" + repeat + ")");
             throw new ArrayIndexOutOfBoundsException();
         }
 
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 8302ece..65b33e5 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -16,14 +16,17 @@
 
 package android.os;
 
-import java.util.ArrayList;
+import java.util.Map;
 
 import android.util.Log;
 
-/** @hide */
+/**
+ * Java API for libvintf.
+ * @hide
+ */
 public class VintfObject {
 
-    private static final String LOG_TAG = "VintfObject";
+    /// ---------- OTA
 
     /**
      * Slurps all device information (both manifests and both matrices)
@@ -45,4 +48,26 @@
      */
     public static native int verify(String[] packageInfo);
 
+    /// ---------- CTS Device Info
+
+    /**
+     * @return a list of HAL names and versions that is supported by this
+     * device as stated in device and framework manifests. For example,
+     * ["android.hidl.manager@1.0", "android.hardware.camera.device@1.0",
+     *  "android.hardware.camera.device@3.2"]. There are no duplicates.
+     */
+    public static native String[] getHalNamesAndVersions();
+
+    /**
+     * @return the BOARD_SEPOLICY_VERS build flag available in device manifest.
+     */
+    public static native String getSepolicyVersion();
+
+    /**
+     * @return a list of VNDK snapshots supported by the framework, as
+     * specified in framework manifest. For example,
+     * [("25.0.5", ["libjpeg.so", "libbase.so"]),
+     *  ("25.1.3", ["libjpeg.so", "libbase.so"])]
+     */
+    public static native Map<String, String[]> getVndkSnapshots();
 }
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 88d17ef..5fd9458 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -15,6 +15,7 @@
  */
 package android.service.autofill;
 
+import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.RemoteException;
@@ -156,6 +157,7 @@
      *
      * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}.
      */
+    @CallSuper
     @Override
     public void onCreate() {
         super.onCreate();
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 69f3f67..af2eb34 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -162,14 +162,18 @@
          *
          * <p>When a user triggers autofill, the system launches the provided intent
          * whose extras will have the {@link
-         * android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once
-         * you complete your authentication flow you should set the activity result to {@link
-         * android.app.Activity#RESULT_OK} and provide the fully populated {@link Dataset
-         * dataset} by setting it to the {@link
-         * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example,
-         * if you provided credit card information without the CVV for the data set in the
-         * {@link FillResponse response} then the returned data set should contain the
-         * CVV entry.</p>
+         * android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen content},
+         * and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE client
+         * state}. Once you complete your authentication flow you should set the activity
+         * result to {@link android.app.Activity#RESULT_OK} and provide the fully populated
+         * {@link Dataset dataset} or a fully-populated {@link FillResponse response} by
+         * setting it to the {@link
+         * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. If you
+         * provide a dataset in the result, it will replace the authenticated dataset and
+         * will be immediately filled in. If you provide a response, it will replace the
+         * current response and the UI will be refreshed. For example, if you provided
+         * credit card information without the CVV for the data set in the {@link FillResponse
+         * response} then the returned data set should contain the CVV entry.
          *
          * <p></><strong>Note:</strong> Do not make the provided pending intent
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
@@ -210,12 +214,15 @@
          *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
-         * @param value value to be auto filled.
+         * @param value value to be auto filled. Pass {@code null} if you do not have the value
+         *        but the target view is a logical part of the dataset. For example, if
+         *        the dataset needs an authentication and you have no access to the value.
+         *        Filtering matches any user typed string to {@code null} values.
          * @return This builder.
          * @throws IllegalStateException if the builder was constructed without a presentation
          * ({@link RemoteViews}).
          */
-        public @NonNull Builder setValue(@NonNull AutofillId id, @NonNull AutofillValue value) {
+        public @NonNull Builder setValue(@NonNull AutofillId id, @Nullable AutofillValue value) {
             throwIfDestroyed();
             if (mPresentation == null) {
                 throw new IllegalStateException("Dataset presentation not set on constructor");
@@ -229,11 +236,14 @@
          *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
-         * @param value value to be auto filled.
+         * @param value value to be auto filled. Pass {@code null} if you do not have the value
+         *        but the target view is a logical part of the dataset. For example, if
+         *        the dataset needs an authentication and you have no access to the value.
+         *        Filtering matches any user typed string to {@code null} values.
          * @param presentation The presentation used to visualize this field.
          * @return This builder.
          */
-        public @NonNull Builder setValue(@NonNull AutofillId id, @NonNull AutofillValue value,
+        public @NonNull Builder setValue(@NonNull AutofillId id, @Nullable AutofillValue value,
                 @NonNull RemoteViews presentation) {
             throwIfDestroyed();
             Preconditions.checkNotNull(presentation, "presentation cannot be null");
@@ -244,7 +254,6 @@
         private void setValueAndPresentation(AutofillId id, AutofillValue value,
                 RemoteViews presentation) {
             Preconditions.checkNotNull(id, "id cannot be null");
-            Preconditions.checkNotNull(value, "value cannot be null");
             if (mFieldIds != null) {
                 final int existingIdx = mFieldIds.indexOf(id);
                 if (existingIdx >= 0) {
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 1914db9..bc96e43 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -236,7 +236,8 @@
          *
          * <p>When a user triggers autofill, the system launches the provided intent
          * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
-         * content}. Once you complete your authentication flow you should set the activity
+         * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
+         * client state}. Once you complete your authentication flow you should set the activity
          * result to {@link android.app.Activity#RESULT_OK} and provide the fully populated
          * {@link FillResponse response} by setting it to the {@link
          * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 277c622..9487760 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -174,6 +174,7 @@
                SAVE_DATA_TYPE_PASSWORD,
                SAVE_DATA_TYPE_ADDRESS,
                SAVE_DATA_TYPE_CREDIT_CARD,
+               SAVE_DATA_TYPE_USERNAME,
                SAVE_DATA_TYPE_EMAIL_ADDRESS})
     @Retention(RetentionPolicy.SOURCE)
     @interface SaveDataType{}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 2b37a23..5ef934e 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -347,7 +347,7 @@
      * <p>Agents that support configuration options should overload this method and return 'true'.
      *
      * @param options The aggregated list of options or an empty list if no restrictions apply.
-     * @return true if the {@link } supports configuration options.
+     * @return true if it supports configuration options.
      */
     public boolean onConfigure(List<PersistableBundle> options) {
         return false;
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 479c9e2..fbc6fc6 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -262,7 +262,8 @@
      * @param keyphrase The keyphrase that's being used, for example "Hello Android".
      * @param locale The locale for which the enrollment needs to be performed.
      * @param callback The callback to notify of detection events.
-     * @return An always-on hotword detector for the given keyphrase and locale.
+     * @return An always-on hotword detector for the given keyphrase and locale. Is null if the
+     * keyphrase and locale is not supported.
      */
     public final AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(
             String keyphrase, Locale locale, AlwaysOnHotwordDetector.Callback callback) {
@@ -272,8 +273,10 @@
         synchronized (mLock) {
             // Allow only one concurrent recognition via the APIs.
             safelyShutdownHotwordDetector();
-            mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
-                    mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            if (isKeyphraseAndLocaleSupportedForHotword(keyphrase, locale)) {
+                mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
+                        mKeyphraseEnrollmentInfo, mInterface, mSystemService);
+            }
         }
         return mHotwordDetector;
     }
@@ -287,6 +290,20 @@
         return mKeyphraseEnrollmentInfo;
     }
 
+    /**
+      * Checks if a given keyphrase and locale are supported to create an
+      * {@link AlwaysOnHotwordDetector}.
+      *
+      * @return true if the keyphrase and locale combination is supported, false otherwise.
+      * @hide
+      */
+    public final boolean isKeyphraseAndLocaleSupportedForHotword(String keyphrase, Locale locale) {
+        if (mKeyphraseEnrollmentInfo == null) {
+            return false;
+        }
+        return mKeyphraseEnrollmentInfo.getKeyphraseMetadata(keyphrase, locale) != null;
+    }
+
     private void safelyShutdownHotwordDetector() {
         try {
             synchronized (mLock) {
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index fc8afe9..9b37a65 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -86,17 +86,5 @@
      * currently, else return the display id of the virtual display
      */
     int getVr2dDisplayId();
-
-    /**
-     * Initiate connection for system controller data.
-     *
-     * @param fd Controller data file descriptor.
-     */
-    void connectController(in FileDescriptor fd);
-
-    /**
-     * Sever connection for system controller data.
-     */
-    void disconnectController();
 }
 
diff --git a/core/java/android/text/ITextClassificationService.aidl b/core/java/android/text/ITextClassificationService.aidl
deleted file mode 100644
index a73dbf0..0000000
--- a/core/java/android/text/ITextClassificationService.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.os.ParcelFileDescriptor;
-
-/**
- * Interface to the text classification service, which grants access to the text classification
- * LSTM model file.
- * {@hide}
- */
-interface ITextClassificationService {
-
-    /**
-     * Request a file descriptor with read-only access to the LSTM model file.
-     * This file descriptor should be closed after the client is done with it.
-     */
-    ParcelFileDescriptor getModelFileFd();
-}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 91f43d6..585f882 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1520,6 +1520,18 @@
     /**
      * Returns a CharSequence concatenating the specified CharSequences,
      * retaining their spans if any.
+     *
+     * If there are no parameters, an empty string will be returned.
+     *
+     * If the number of parameters is exactly one, that parameter is returned as output, even if it
+     * is null.
+     *
+     * If the number of parameters is at least two, any null CharSequence among the parameters is
+     * treated as if it was the string <code>"null"</code>.
+     *
+     * If there are paragraph spans in the source CharSequences that satisfy paragraph boundary
+     * requirements in the sources but would no longer satisfy them in the concatenated
+     * CharSequence, they may get extended in the resulting CharSequence or not retained.
      */
     public static CharSequence concat(CharSequence... text) {
         if (text.length == 0) {
@@ -1531,35 +1543,29 @@
         }
 
         boolean spanned = false;
-        for (int i = 0; i < text.length; i++) {
-            if (text[i] instanceof Spanned) {
+        for (CharSequence piece : text) {
+            if (piece instanceof Spanned) {
                 spanned = true;
                 break;
             }
         }
 
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < text.length; i++) {
-            sb.append(text[i]);
-        }
-
-        if (!spanned) {
+        if (spanned) {
+            final SpannableStringBuilder ssb = new SpannableStringBuilder();
+            for (CharSequence piece : text) {
+                // If a piece is null, we append the string "null" for compatibility with the
+                // behavior of StringBuilder and the behavior of the concat() method in earlier
+                // versions of Android.
+                ssb.append(piece == null ? "null" : piece);
+            }
+            return new SpannedString(ssb);
+        } else {
+            final StringBuilder sb = new StringBuilder();
+            for (CharSequence piece : text) {
+                sb.append(piece);
+            }
             return sb.toString();
         }
-
-        SpannableString ss = new SpannableString(sb);
-        int off = 0;
-        for (int i = 0; i < text.length; i++) {
-            int len = text[i].length();
-
-            if (text[i] instanceof Spanned) {
-                copySpansFrom((Spanned) text[i], 0, len, Object.class, ss, off);
-            }
-
-            off += len;
-        }
-
-        return new SpannedString(ss);
     }
 
     /**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index f539752..2ade9b5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -678,6 +678,7 @@
                     mIsCreating = false;
                     if (mSurfaceControl != null && !mSurfaceCreated) {
                         mSurfaceControl.destroy();
+                        mSurface.release();
                         mSurfaceControl = null;
                     }
                 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e9e9d7c..ff42ff6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6844,7 +6844,7 @@
         if (isAutofillable() && isAttachedToWindow()) {
             AutofillManager afm = getAutofillManager();
             if (afm != null) {
-                if (enter && hasWindowFocus() && isFocused()) {
+                if (enter && hasWindowFocus() && isFocused() && isVisibleToUser()) {
                     afm.notifyViewEntered(this);
                 } else if (!hasWindowFocus() || !isFocused()) {
                     afm.notifyViewExited(this);
@@ -7237,44 +7237,53 @@
 
         RectF position = mAttachInfo.mTmpTransformRect;
         position.set(0, 0, mRight - mLeft, mBottom - mTop);
+        mapRectFromViewToScreenCoords(position, clipToParent);
+        outRect.set(Math.round(position.left), Math.round(position.top),
+                Math.round(position.right), Math.round(position.bottom));
+    }
 
+    /**
+     * Map a rectangle from view-relative coordinates to screen-relative coordinates
+     *
+     * @param rect The rectangle to be mapped
+     * @param clipToParent Whether to clip child bounds to the parent ones.
+     * @hide
+     */
+    public void mapRectFromViewToScreenCoords(RectF rect, boolean clipToParent) {
         if (!hasIdentityMatrix()) {
-            getMatrix().mapRect(position);
+            getMatrix().mapRect(rect);
         }
 
-        position.offset(mLeft, mTop);
+        rect.offset(mLeft, mTop);
 
         ViewParent parent = mParent;
         while (parent instanceof View) {
             View parentView = (View) parent;
 
-            position.offset(-parentView.mScrollX, -parentView.mScrollY);
+            rect.offset(-parentView.mScrollX, -parentView.mScrollY);
 
             if (clipToParent) {
-                position.left = Math.max(position.left, 0);
-                position.top = Math.max(position.top, 0);
-                position.right = Math.min(position.right, parentView.getWidth());
-                position.bottom = Math.min(position.bottom, parentView.getHeight());
+                rect.left = Math.max(rect.left, 0);
+                rect.top = Math.max(rect.top, 0);
+                rect.right = Math.min(rect.right, parentView.getWidth());
+                rect.bottom = Math.min(rect.bottom, parentView.getHeight());
             }
 
             if (!parentView.hasIdentityMatrix()) {
-                parentView.getMatrix().mapRect(position);
+                parentView.getMatrix().mapRect(rect);
             }
 
-            position.offset(parentView.mLeft, parentView.mTop);
+            rect.offset(parentView.mLeft, parentView.mTop);
 
             parent = parentView.mParent;
         }
 
         if (parent instanceof ViewRootImpl) {
             ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
-            position.offset(0, -viewRootImpl.mCurScrollY);
+            rect.offset(0, -viewRootImpl.mCurScrollY);
         }
 
-        position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
-
-        outRect.set(Math.round(position.left), Math.round(position.top),
-                Math.round(position.right), Math.round(position.bottom));
+        rect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
     }
 
     /**
@@ -7295,7 +7304,7 @@
      * fills in all data that can be inferred from the view itself.
      */
     public void onProvideStructure(ViewStructure structure) {
-        onProvideStructureForAssistOrAutofill(structure, false);
+        onProvideStructureForAssistOrAutofill(structure, false, 0);
     }
 
     /**
@@ -7309,6 +7318,9 @@
      *   <li>It must set fields such {@link ViewStructure#setText(CharSequence)},
      * {@link ViewStructure#setAutofillOptions(CharSequence[])},
      * or {@link ViewStructure#setWebDomain(String)}.
+     *   <li> The {@code left} and {@code top} values set in
+     * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
+     * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
      * </ul>
      *
      * @param structure Fill in with structured view data. The default implementation
@@ -7317,12 +7329,12 @@
      *
      * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
      */
-    public void onProvideAutofillStructure(ViewStructure structure, int flags) {
-        onProvideStructureForAssistOrAutofill(structure, true);
+    public void onProvideAutofillStructure(ViewStructure structure, @AutofillFlags int flags) {
+        onProvideStructureForAssistOrAutofill(structure, true, flags);
     }
 
     private void onProvideStructureForAssistOrAutofill(ViewStructure structure,
-            boolean forAutofill) {
+            boolean forAutofill, @AutofillFlags int flags) {
         final int id = mID;
         if (id != NO_ID && !isViewIdGenerated(id)) {
             String pkg, type, entry;
@@ -7350,11 +7362,37 @@
             }
         }
 
-        structure.setDimens(mLeft, mTop, mScrollX, mScrollY, mRight - mLeft, mBottom - mTop);
-        if (!hasIdentityMatrix()) {
-            structure.setTransformation(getMatrix());
+        int ignoredParentLeft = 0;
+        int ignoredParentTop = 0;
+        if (forAutofill && (flags & AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) == 0) {
+            View parentGroup = null;
+
+            ViewParent viewParent = getParent();
+            if (viewParent instanceof View) {
+                parentGroup = (View) viewParent;
+            }
+
+            while (parentGroup != null && !parentGroup.isImportantForAutofill()) {
+                ignoredParentLeft += parentGroup.mLeft;
+                ignoredParentTop += parentGroup.mTop;
+
+                viewParent = parentGroup.getParent();
+                if (viewParent instanceof View) {
+                    parentGroup = (View) viewParent;
+                } else {
+                    break;
+                }
+            }
         }
-        structure.setElevation(getZ());
+
+        structure.setDimens(ignoredParentLeft + mLeft, ignoredParentTop + mTop, mScrollX, mScrollY,
+                mRight - mLeft, mBottom - mTop);
+        if (!forAutofill) {
+            if (!hasIdentityMatrix()) {
+                structure.setTransformation(getMatrix());
+            }
+            structure.setElevation(getZ());
+        }
         structure.setVisibility(getVisibility());
         structure.setEnabled(isEnabled());
         if (isClickable()) {
@@ -7434,10 +7472,15 @@
      * <li>Call {@link AutofillManager#cancel()} ()} when the autofill context
      * of the view structure changed and you want the current autofill interaction if such
      * to be cancelled.
+     * <li> The {@code left} and {@code top} values set in
+     * {@link ViewStructure#setDimens(int, int, int, int, int, int)} need to be relative to the next
+     * {@link ViewGroup#isImportantForAutofill() included} parent in the structure.
      * </ol>
      *
      * @param structure Fill in with structured view data.
-     * @param flags optional flags (currently {@code 0}).
+     * @param flags optional flags.
+     *
+     * @see #AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
      */
     public void onProvideAutofillVirtualStructure(ViewStructure structure, int flags) {
     }
@@ -7695,7 +7738,8 @@
     }
 
     private boolean isAutofillable() {
-        return getAutofillType() != AUTOFILL_TYPE_NONE && isImportantForAutofill();
+        return getAutofillType() != AUTOFILL_TYPE_NONE && isImportantForAutofill()
+                && getAccessibilityViewId() > LAST_APP_ACCESSIBILITY_ID;
     }
 
     private void populateVirtualStructure(ViewStructure structure,
@@ -7760,7 +7804,7 @@
      * {@link #onProvideVirtualStructure}.
      */
     public void dispatchProvideStructure(ViewStructure structure) {
-        dispatchProvideStructureForAssistOrAutofill(structure, false);
+        dispatchProvideStructureForAssistOrAutofill(structure, false, 0);
     }
 
     /**
@@ -7793,16 +7837,15 @@
      */
     public void dispatchProvideAutofillStructure(@NonNull ViewStructure structure,
             @AutofillFlags int flags) {
-        dispatchProvideStructureForAssistOrAutofill(structure, true);
+        dispatchProvideStructureForAssistOrAutofill(structure, true, flags);
     }
 
     private void dispatchProvideStructureForAssistOrAutofill(ViewStructure structure,
-            boolean forAutofill) {
+            boolean forAutofill, @AutofillFlags int flags) {
         if (forAutofill) {
             structure.setAutofillId(getAutofillId());
-            // NOTE: flags are not currently supported, hence 0
-            onProvideAutofillStructure(structure, 0);
-            onProvideAutofillVirtualStructure(structure, 0);
+            onProvideAutofillStructure(structure, flags);
+            onProvideAutofillVirtualStructure(structure, flags);
         } else if (!isAssistBlocked()) {
             onProvideStructure(structure);
             onProvideVirtualStructure(structure);
@@ -20419,9 +20462,10 @@
     @Nullable private Drawable getAutofilledDrawable() {
         // Lazily load the isAutofilled drawable.
         if (mAttachInfo.mAutofilledDrawable == null) {
-            TypedArray a = mContext.getTheme().obtainStyledAttributes(AUTOFILL_HIGHLIGHT_ATTR);
+            Context rootContext = getRootView().getContext();
+            TypedArray a = rootContext.getTheme().obtainStyledAttributes(AUTOFILL_HIGHLIGHT_ATTR);
             int attributeResourceId = a.getResourceId(0, 0);
-            mAttachInfo.mAutofilledDrawable = mContext.getDrawable(attributeResourceId);
+            mAttachInfo.mAutofilledDrawable = rootContext.getDrawable(attributeResourceId);
             a.recycle();
         }
 
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index a432d30..6dd8ecf 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -480,13 +480,6 @@
         public void onWindowFocusChanged(boolean hasFocus);
 
         /**
-         * @hide
-         */
-        default void onBeforeAttachedToWindow() {
-            // empty
-        }
-
-        /**
          * Called when the window has been attached to the window manager.
          * See {@link View#onAttachedToWindow() View.onAttachedToWindow()}
          * for more information.
diff --git a/core/java/android/view/WindowCallbackWrapper.java b/core/java/android/view/WindowCallbackWrapper.java
index 7018529..02c8945 100644
--- a/core/java/android/view/WindowCallbackWrapper.java
+++ b/core/java/android/view/WindowCallbackWrapper.java
@@ -109,11 +109,6 @@
     }
 
     @Override
-    public void onBeforeAttachedToWindow() {
-        mWrapped.onBeforeAttachedToWindow();
-    }
-
-    @Override
     public void onAttachedToWindow() {
         mWrapped.onAttachedToWindow();
     }
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 143c49a..604e985 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -309,6 +309,13 @@
 
                 final int oldChildCount = oldInfo.getChildCount();
                 for (int i = 0; i < oldChildCount; i++) {
+                    if (nodes.get(sourceId) == null) {
+                        // We've removed (and thus recycled) this node because it was its own
+                        // ancestor (the app gave us bad data), we can't continue using it.
+                        // Clear the cache for this window and give up on adding the node.
+                        clearNodesForWindowLocked(windowId);
+                        return;
+                    }
                     final long oldChildId = oldInfo.getChildId(i);
                     // If the child is no longer present, remove the sub-tree.
                     if (newChildrenIds == null || newChildrenIds.indexOf(oldChildId) < 0) {
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index f8a13a3..79c81b2 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -630,7 +630,8 @@
     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
 
     /**
-     * Represents the event of scrolling a view.
+     * Represents the event of scrolling a view. This event type is generally not sent directly.
+     * @see View#onScrollChanged(int, int, int, int)
      */
     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
 
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index d0133ed..75a9965 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -28,7 +28,6 @@
 import android.graphics.Rect;
 import android.metrics.LogMaker;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.service.autofill.AutofillService;
@@ -38,7 +37,6 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
-import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
@@ -47,6 +45,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
@@ -118,6 +117,48 @@
     /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2;
     /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4;
 
+    /** Which bits in an authentication id are used for the dataset id */
+    private static final int AUTHENTICATION_ID_DATASET_ID_MASK = 0xFFFF;
+    /** How many bits in an authentication id are used for the dataset id */
+    private static final int AUTHENTICATION_ID_DATASET_ID_SHIFT = 16;
+    /** @hide The index for an undefined data set */
+    public static final int AUTHENTICATION_ID_DATASET_ID_UNDEFINED = 0xFFFF;
+
+    /**
+     * Makes an authentication id from a request id and a dataset id.
+     *
+     * @param requestId The request id.
+     * @param datasetId The dataset id.
+     * @return The authentication id.
+     * @hide
+     */
+    public static int makeAuthenticationId(int requestId, int datasetId) {
+        return (requestId << AUTHENTICATION_ID_DATASET_ID_SHIFT)
+                | (datasetId & AUTHENTICATION_ID_DATASET_ID_MASK);
+    }
+
+    /**
+     * Gets the request id from an authentication id.
+     *
+     * @param authRequestId The authentication id.
+     * @return The request id.
+     * @hide
+     */
+    public static int getRequestIdFromAuthenticationId(int authRequestId) {
+        return (authRequestId >> AUTHENTICATION_ID_DATASET_ID_SHIFT);
+    }
+
+    /**
+     * Gets the dataset id from an authentication id.
+     *
+     * @param authRequestId The authentication id.
+     * @return The dataset id.
+     * @hide
+     */
+    public static int getDatasetIdFromAuthenticationId(int authRequestId) {
+        return (authRequestId & AUTHENTICATION_ID_DATASET_ID_MASK);
+    }
+
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     /**
@@ -157,10 +198,12 @@
         /**
          * Asks the client to start an authentication flow.
          *
+         * @param authenticationId A unique id of the authentication operation.
          * @param intent The authentication intent.
          * @param fillInIntent The authentication fill-in intent.
          */
-        void autofillCallbackAuthenticate(IntentSender intent, Intent fillInIntent);
+        void autofillCallbackAuthenticate(int authenticationId, IntentSender intent,
+                Intent fillInIntent);
 
         /**
          * Tells the client this manager has state to be reset.
@@ -188,11 +231,11 @@
         boolean autofillCallbackRequestHideFillUi();
 
         /**
-         * Checks if the view is currently attached and visible.
+         * Checks if views are currently attached and visible.
          *
-         * @return {@code true} iff the view is attached or visible
+         * @return And array with {@code true} iff the view is attached or visible
          */
-        boolean getViewVisibility(int viewId);
+        @NonNull boolean[] getViewVisibility(@NonNull int[] viewId);
 
         /**
          * Checks is the client is currently visible as understood by autofill.
@@ -200,6 +243,15 @@
          * @return {@code true} if the client is currently visible
          */
         boolean isVisibleForAutofill();
+
+        /**
+         * Find views by traversing the hierarchies of the client.
+         *
+         * @param viewIds The accessibility ids of the views to find
+         *
+         * @return And array containing the views, or {@code null} if not found
+         */
+        @NonNull View[] findViewsByAccessibilityIdTraversal(@NonNull int[] viewIds);
     }
 
     /**
@@ -259,30 +311,6 @@
     }
 
     /**
-     * Set window future popup windows should be attached to.
-     *
-     * @param windowToken The window the popup windows should be attached to
-     *
-     * {@hide}
-     */
-    public void onAttachedToWindow(@NonNull IBinder windowToken) {
-        if (!hasAutofillFeature()) {
-            return;
-        }
-        synchronized (mLock) {
-            if (mSessionId == NO_SESSION) {
-                return;
-            }
-
-            try {
-                mService.setWindow(mSessionId, windowToken);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Could not attach window to session " + mSessionId);
-            }
-        }
-    }
-
-    /**
      * Called once the client becomes visible.
      *
      * @see AutofillClient#isVisibleForAutofill()
@@ -292,7 +320,7 @@
     public void onVisibleForAutofill() {
         synchronized (mLock) {
             if (mEnabled && mSessionId != NO_SESSION && mTrackedViews != null) {
-                mTrackedViews.onVisibleForAutofill();
+                mTrackedViews.onVisibleForAutofillLocked();
             }
         }
     }
@@ -406,7 +434,7 @@
 
                 if (mSessionId == NO_SESSION) {
                     // Starts new session.
-                    startSessionLocked(id, view.getWindowToken(), null, value, flags);
+                    startSessionLocked(id, null, value, flags);
                 } else {
                     // Update focus on existing session.
                     updateSessionLocked(id, null, value, ACTION_VIEW_ENTERED, flags);
@@ -484,7 +512,7 @@
 
                 if (mSessionId == NO_SESSION) {
                     // Starts new session.
-                    startSessionLocked(id, view.getWindowToken(), bounds, null, flags);
+                    startSessionLocked(id, bounds, null, flags);
                 } else {
                     // Update focus on existing session.
                     updateSessionLocked(id, bounds, null, ACTION_VIEW_ENTERED, flags);
@@ -691,7 +719,7 @@
     }
 
     /** @hide */
-    public void onAuthenticationResult(Intent data) {
+    public void onAuthenticationResult(int authenticationId, Intent data) {
         if (!hasAutofillFeature()) {
             return;
         }
@@ -710,7 +738,8 @@
             final Bundle responseData = new Bundle();
             responseData.putParcelable(EXTRA_AUTHENTICATION_RESULT, result);
             try {
-                mService.setAuthenticationResult(responseData, mSessionId, mContext.getUserId());
+                mService.setAuthenticationResult(responseData, mSessionId, authenticationId,
+                        mContext.getUserId());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error delivering authentication result", e);
             }
@@ -725,15 +754,15 @@
         return new AutofillId(parent.getAccessibilityViewId(), childId);
     }
 
-    private void startSessionLocked(@NonNull AutofillId id, @NonNull IBinder windowToken,
-            @NonNull Rect bounds, @NonNull AutofillValue value, int flags) {
+    private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds,
+            @NonNull AutofillValue value, int flags) {
         if (sVerbose) {
             Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value
                     + ", flags=" + flags);
         }
 
         try {
-            mSessionId = mService.startSession(mContext.getActivityToken(), windowToken,
+            mSessionId = mService.startSession(mContext.getActivityToken(),
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
                     mCallback != null, flags, mContext.getOpPackageName());
             final AutofillClient client = getClientLocked();
@@ -855,9 +884,9 @@
         }
     }
 
-    private void requestShowFillUi(int sessionId, IBinder windowToken, AutofillId id, int width,
-            int height, Rect anchorBounds, IAutofillWindowPresenter presenter) {
-        final View anchor = findAchorView(windowToken, id);
+    private void requestShowFillUi(int sessionId, AutofillId id, int width, int height,
+            Rect anchorBounds, IAutofillWindowPresenter presenter) {
+        final View anchor = findView(id);
         if (anchor == null) {
             return;
         }
@@ -886,12 +915,13 @@
         }
     }
 
-    private void authenticate(int sessionId, IntentSender intent, Intent fillInIntent) {
+    private void authenticate(int sessionId, int authenticationId, IntentSender intent,
+            Intent fillInIntent) {
         synchronized (mLock) {
             if (sessionId == mSessionId) {
                 AutofillClient client = getClientLocked();
                 if (client != null) {
-                    client.autofillCallbackAuthenticate(intent, fillInIntent);
+                    client.autofillCallbackAuthenticate(authenticationId, intent, fillInIntent);
                 }
             }
         }
@@ -930,27 +960,27 @@
         }
     }
 
-    private void autofill(int sessionId, IBinder windowToken, List<AutofillId> ids,
-            List<AutofillValue> values) {
+    private void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) {
         synchronized (mLock) {
             if (sessionId != mSessionId) {
                 return;
             }
 
-            final View root = WindowManagerGlobal.getInstance().getWindowView(windowToken);
-            if (root == null) {
+            final AutofillClient client = getClientLocked();
+            if (client == null) {
                 return;
             }
 
             final int itemCount = ids.size();
             int numApplied = 0;
             ArrayMap<View, SparseArray<AutofillValue>> virtualValues = null;
+            final View[] views = client.findViewsByAccessibilityIdTraversal(getViewIds(ids));
 
             for (int i = 0; i < itemCount; i++) {
                 final AutofillId id = ids.get(i);
                 final AutofillValue value = values.get(i);
                 final int viewId = id.getViewId();
-                final View view = root.findViewByAccessibilityIdTraversal(viewId);
+                final View view = views[i];
                 if (view == null) {
                     Log.w(TAG, "autofill(): no View with id " + viewId);
                     continue;
@@ -1022,8 +1052,11 @@
         }
     }
 
-    private void requestHideFillUi(int sessionId, IBinder windowToken, AutofillId id) {
-        final View anchor = findAchorView(windowToken, id);
+    private void requestHideFillUi(int sessionId, AutofillId id) {
+        final View anchor = findView(id);
+        if (anchor == null) {
+            return;
+        }
 
         AutofillCallback callback = null;
         synchronized (mLock) {
@@ -1049,8 +1082,11 @@
         }
     }
 
-    private void notifyNoFillUi(int sessionId, IBinder windowToken, AutofillId id) {
-        final View anchor = findAchorView(windowToken, id);
+    private void notifyNoFillUi(int sessionId, AutofillId id) {
+        final View anchor = findView(id);
+        if (anchor == null) {
+            return;
+        }
 
         AutofillCallback callback = null;
         synchronized (mLock) {
@@ -1070,18 +1106,38 @@
         }
     }
 
-    private View findAchorView(IBinder windowToken, AutofillId id) {
-        final View root = WindowManagerGlobal.getInstance().getWindowView(windowToken);
-        if (root == null) {
-            Log.w(TAG, "no window with token " + windowToken);
+    /**
+     * Get an array of viewIds from a List of {@link AutofillId}.
+     *
+     * @param autofillIds The autofill ids to convert
+     *
+     * @return The array of viewIds.
+     */
+    @NonNull private int[] getViewIds(@NonNull List<AutofillId> autofillIds) {
+        final int numIds = autofillIds.size();
+        final int[] viewIds = new int[numIds];
+        for (int i = 0; i < numIds; i++) {
+            viewIds[i] = autofillIds.get(i).getViewId();
+        }
+
+        return viewIds;
+    }
+
+    /**
+     * Find a single view by its id.
+     *
+     * @param autofillId The autofill id of the view
+     *
+     * @return The view or {@code null} if view was not found
+     */
+    private View findView(@NonNull AutofillId autofillId) {
+        final AutofillClient client = getClientLocked();
+
+        if (client == null) {
             return null;
         }
-        final View view = root.findViewByAccessibilityIdTraversal(id.getViewId());
-        if (view == null) {
-            Log.w(TAG, "no view with id " + id);
-            return null;
-        }
-        return view;
+
+        return client.findViewsByAccessibilityIdTraversal(new int[]{autofillId.getViewId()})[0];
     }
 
     /** @hide */
@@ -1160,22 +1216,26 @@
          *
          * @param trackedIds The views to be tracked
          */
-        TrackedViews(@NonNull List<AutofillId> trackedIds) {
+        TrackedViews(List<AutofillId> trackedIds) {
             mVisibleTrackedIds = null;
             mInvisibleTrackedIds = null;
 
             AutofillClient client = getClientLocked();
-            if (trackedIds != null) {
-                int numIds = trackedIds.size();
+            if (trackedIds != null && client != null) {
+                final boolean[] isVisible;
+
+                if (client.isVisibleForAutofill()) {
+                    isVisible = client.getViewVisibility(getViewIds(trackedIds));
+                } else {
+                    // All false
+                    isVisible = new boolean[trackedIds.size()];
+                }
+
+                final int numIds = trackedIds.size();
                 for (int i = 0; i < numIds; i++) {
-                    AutofillId id = trackedIds.get(i);
+                    final AutofillId id = trackedIds.get(i);
 
-                    boolean isVisible = true;
-                    if (client != null && client.isVisibleForAutofill()) {
-                        isVisible = client.getViewVisibility(id.getViewId());
-                    }
-
-                    if (isVisible) {
+                    if (isVisible[i]) {
                         mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
                     } else {
                         mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
@@ -1233,16 +1293,23 @@
          *
          * @see AutofillClient#isVisibleForAutofill()
          */
-        void onVisibleForAutofill() {
-            // The visibility of the views might have changed while the client was not started,
+        void onVisibleForAutofillLocked() {
+            // The visibility of the views might have changed while the client was not be visible,
             // hence update the visibility state for all views.
             AutofillClient client = getClientLocked();
             ArraySet<AutofillId> updatedVisibleTrackedIds = null;
             ArraySet<AutofillId> updatedInvisibleTrackedIds = null;
             if (client != null) {
                 if (mInvisibleTrackedIds != null) {
-                    for (AutofillId id : mInvisibleTrackedIds) {
-                        if (client.getViewVisibility(id.getViewId())) {
+                    final ArrayList<AutofillId> orderedInvisibleIds =
+                            new ArrayList<>(mInvisibleTrackedIds);
+                    final boolean[] isVisible = client.getViewVisibility(
+                            getViewIds(orderedInvisibleIds));
+
+                    final int numInvisibleTrackedIds = orderedInvisibleIds.size();
+                    for (int i = 0; i < numInvisibleTrackedIds; i++) {
+                        final AutofillId id = orderedInvisibleIds.get(i);
+                        if (isVisible[i]) {
                             updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
 
                             if (sDebug) {
@@ -1255,8 +1322,16 @@
                 }
 
                 if (mVisibleTrackedIds != null) {
-                    for (AutofillId id : mVisibleTrackedIds) {
-                        if (client.getViewVisibility(id.getViewId())) {
+                    final ArrayList<AutofillId> orderedVisibleIds =
+                            new ArrayList<>(mVisibleTrackedIds);
+                    final boolean[] isVisible = client.getViewVisibility(
+                            getViewIds(orderedVisibleIds));
+
+                    final int numVisibleTrackedIds = orderedVisibleIds.size();
+                    for (int i = 0; i < numVisibleTrackedIds; i++) {
+                        final AutofillId id = orderedVisibleIds.get(i);
+
+                        if (isVisible[i]) {
                             updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
                         } else {
                             updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
@@ -1355,50 +1430,49 @@
         }
 
         @Override
-        public void autofill(int sessionId, IBinder windowToken, List<AutofillId> ids,
-                List<AutofillValue> values) {
+        public void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
                 afm.mContext.getMainThreadHandler().post(
-                        () -> afm.autofill(sessionId, windowToken, ids, values));
+                        () -> afm.autofill(sessionId, ids, values));
             }
         }
 
         @Override
-        public void authenticate(int sessionId, IntentSender intent, Intent fillInIntent) {
+        public void authenticate(int sessionId, int authenticationId, IntentSender intent,
+                Intent fillInIntent) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
                 afm.mContext.getMainThreadHandler().post(
-                        () -> afm.authenticate(sessionId, intent, fillInIntent));
+                        () -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
             }
         }
 
         @Override
-        public void requestShowFillUi(int sessionId, IBinder windowToken, AutofillId id,
-                int width, int height, Rect anchorBounds, IAutofillWindowPresenter presenter) {
+        public void requestShowFillUi(int sessionId, AutofillId id, int width, int height,
+                Rect anchorBounds, IAutofillWindowPresenter presenter) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
                 afm.mContext.getMainThreadHandler().post(
-                        () -> afm.requestShowFillUi(sessionId, windowToken, id, width, height,
-                                anchorBounds, presenter));
+                        () -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds,
+                                presenter));
             }
         }
 
         @Override
-        public void requestHideFillUi(int sessionId, IBinder windowToken, AutofillId id) {
+        public void requestHideFillUi(int sessionId, AutofillId id) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
                 afm.mContext.getMainThreadHandler().post(
-                        () -> afm.requestHideFillUi(sessionId, windowToken, id));
+                        () -> afm.requestHideFillUi(sessionId, id));
             }
         }
 
         @Override
-        public void notifyNoFillUi(int sessionId, IBinder windowToken, AutofillId id) {
+        public void notifyNoFillUi(int sessionId, AutofillId id) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
-                afm.mContext.getMainThreadHandler().post(
-                        () -> afm.notifyNoFillUi(sessionId, windowToken, id));
+                afm.mContext.getMainThreadHandler().post(() -> afm.notifyNoFillUi(sessionId, id));
             }
         }
 
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index f28d8ba..a12e956 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -32,17 +32,16 @@
 interface IAutoFillManager {
     // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE
     int addClient(in IAutoFillManagerClient client, int userId);
-    int startSession(IBinder activityToken, IBinder windowToken, in IBinder appCallback,
-            in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
-            boolean hasCallback, int flags, String packageName);
+    int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
+            in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
+            String packageName);
     FillEventHistory getFillEventHistory();
     boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
-    void setWindow(int sessionId, in IBinder windowToken);
     void updateSession(int sessionId, in AutofillId id, in Rect bounds,
             in AutofillValue value, int action, int flags, int userId);
     void finishSession(int sessionId, int userId);
     void cancelSession(int sessionId, int userId);
-    void setAuthenticationResult(in Bundle data, int sessionId, int userId);
+    void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);
     void setHasCallback(int sessionId, int userId, boolean hasIt);
     void disableOwnedAutofillServices(int userId);
     boolean isServiceSupported(int userId);
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index aef98b7..1d66f7f 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -40,13 +40,13 @@
     /**
       * Autofills the activity with the contents of a dataset.
       */
-    void autofill(int sessionId, in IBinder windowToken, in List<AutofillId> ids,
-            in List<AutofillValue> values);
+    void autofill(int sessionId, in List<AutofillId> ids, in List<AutofillValue> values);
 
     /**
       * Authenticates a fill response or a data set.
       */
-    void authenticate(int sessionId, in IntentSender intent, in Intent fillInIntent);
+    void authenticate(int sessionId, int authenticationId, in IntentSender intent,
+            in Intent fillInIntent);
 
     /**
       * Sets the views to track. If saveOnAllViewsInvisible is set and all these view are invisible
@@ -58,18 +58,18 @@
     /**
      * Requests showing the fill UI.
      */
-    void requestShowFillUi(int sessionId, in IBinder windowToken, in AutofillId id, int width,
-            int height, in Rect anchorBounds, in IAutofillWindowPresenter presenter);
+    void requestShowFillUi(int sessionId, in AutofillId id, int width, int height,
+    in Rect anchorBounds, in IAutofillWindowPresenter presenter);
 
     /**
      * Requests hiding the fill UI.
      */
-    void requestHideFillUi(int sessionId, in IBinder windowToken, in AutofillId id);
+    void requestHideFillUi(int sessionId, in AutofillId id);
 
     /**
      * Notifies no fill UI will be shown.
      */
-    void notifyNoFillUi(int sessionId, in IBinder windowToken, in AutofillId id);
+    void notifyNoFillUi(int sessionId, in AutofillId id);
 
     /**
      * Starts the provided intent sender
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index a081f0b..7362c70 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -102,7 +102,9 @@
                         string, selectionStartIndex, selectionEndIndex);
                 final int start = startEnd[0];
                 final int end = startEnd[1];
-                if (start >= 0 && end <= string.length() && start <= end) {
+                if (start <= end
+                        && start >= 0 && end <= string.length()
+                        && start <= selectionStartIndex && end >= selectionEndIndex) {
                     final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
                     final SmartSelection.ClassificationResult[] results =
                             smartSelection.classifyText(
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 2e2056c..779eefb 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -29,6 +29,8 @@
 import com.android.internal.textservice.ITextServicesManager;
 import com.android.internal.textservice.ITextServicesSessionListener;
 
+import dalvik.system.CloseGuard;
+
 import java.util.LinkedList;
 import java.util.Queue;
 
@@ -98,7 +100,7 @@
     private final SpellCheckerSessionListener mSpellCheckerSessionListener;
     private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
 
-    private boolean mIsUsed;
+    private final CloseGuard mGuard = CloseGuard.get();
 
     /** Handler that will execute the main tasks */
     private final Handler mHandler = new Handler() {
@@ -128,8 +130,9 @@
         mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
         mInternalListener = new InternalListener(mSpellCheckerSessionListenerImpl);
         mTextServicesManager = tsm;
-        mIsUsed = true;
         mSpellCheckerSessionListener = listener;
+
+        mGuard.open("finishSession");
     }
 
     /**
@@ -160,7 +163,7 @@
      * checker.
      */
     public void close() {
-        mIsUsed = false;
+        mGuard.close();
         try {
             mSpellCheckerSessionListenerImpl.close();
             mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
@@ -542,11 +545,14 @@
 
     @Override
     protected void finalize() throws Throwable {
-        super.finalize();
-        if (mIsUsed) {
-            Log.e(TAG, "SpellCheckerSession was not finished properly." +
-                    "You should call finishSession() when you finished to use a spell checker.");
-            close();
+        try {
+            // Note that mGuard will be null if the constructor threw.
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+                close();
+            }
+        } finally {
+            super.finalize();
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 52c82a7..ecb25fe 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -98,7 +98,7 @@
  * invoke the Browser application with a URL Intent rather than show it
  * with a WebView. For example:
  * <pre>
- * Uri uri = Uri.parse("http://www.example.com");
+ * Uri uri = Uri.parse("https://www.example.com");
  * Intent intent = new Intent(Intent.ACTION_VIEW, uri);
  * startActivity(intent);
  * </pre>
@@ -116,7 +116,7 @@
  * <pre>
  * // Simplest usage: note that an exception will NOT be thrown
  * // if there is an error loading this page (see below).
- * webview.loadUrl("http://slashdot.org/");
+ * webview.loadUrl("https://example.com/");
  *
  * // OR, you can also load from an HTML string:
  * String summary = "&lt;html>&lt;body>You scored &lt;b>192&lt;/b> points.&lt;/body>&lt;/html>";
@@ -175,7 +175,7 @@
  *   }
  * });
  *
- * webview.loadUrl("http://developer.android.com/");
+ * webview.loadUrl("https://developer.android.com/");
  * </pre>
  *
  * <h3>Zoom</h3>
@@ -2705,7 +2705,7 @@
      * <p>Example2: an IFRAME tag.
      *
      * <pre class="prettyprint">
-     *    <iframe src="http://example.com/login"/>
+     *    <iframe src="https://example.com/login"/>
      * </pre>
      *
      * <p>Would map to:
@@ -2714,7 +2714,7 @@
      *     int index = structure.addChildCount(1);
      *     ViewStructure iframe = structure.newChildFor(index);
      *     iframe.setHtmlInfo(child.newHtmlInfoBuilder("iframe")
-     *         .addAttribute("url", "http://example.com/login")
+     *         .addAttribute("url", "https://example.com/login")
      *         .build());
      * </pre>
      */
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 569fe01..5845719 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -30,6 +30,7 @@
 import android.os.Bundle;
 import android.os.Trace;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.MathUtils;
 import android.util.SparseBooleanArray;
 import android.view.FocusFinder;
@@ -147,6 +148,8 @@
  */
 @RemoteView
 public class ListView extends AbsListView {
+    static final String TAG = "ListView";
+
     /**
      * Used to indicate a no preference for a position type.
      */
@@ -335,6 +338,12 @@
      * @param isSelectable whether the item is selectable
      */
     public void addHeaderView(View v, Object data, boolean isSelectable) {
+        if (v.getParent() != null && v.getParent() != this) {
+            if (Log.isLoggable(TAG, Log.WARN)) {
+                Log.w(TAG, "The specified child already has a parent. "
+                           + "You must call removeView() on the child's parent first.");
+            }
+        }
         final FixedViewInfo info = new FixedViewInfo();
         info.view = v;
         info.data = data;
@@ -429,6 +438,13 @@
      * @param isSelectable true if the footer view can be selected
      */
     public void addFooterView(View v, Object data, boolean isSelectable) {
+        if (v.getParent() != null && v.getParent() != this) {
+            if (Log.isLoggable(TAG, Log.WARN)) {
+                Log.w(TAG, "The specified child already has a parent. "
+                           + "You must call removeView() on the child's parent first.");
+            }
+        }
+
         final FixedViewInfo info = new FixedViewInfo();
         info.view = v;
         info.data = data;
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7bdd6da..d456989 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -737,6 +737,7 @@
         mInputText.setFilters(new InputFilter[] {
             new InputTextFilter()
         });
+        mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
 
         mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
         mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -770,6 +771,12 @@
         if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
+
+        // Should be focusable by default, as the text view whose visibility changes is focusable
+        if (getFocusable() == View.FOCUSABLE_AUTO) {
+            setFocusable(View.FOCUSABLE);
+            setFocusableInTouchMode(true);
+        }
     }
 
     @Override
@@ -856,7 +863,7 @@
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
                 removeAllCallbacks();
-                mInputText.setVisibility(View.INVISIBLE);
+                hideSoftInput();
                 mLastDownOrMoveEventY = mLastDownEventY = event.getY();
                 mLastDownEventTime = event.getEventTime();
                 mIgnoreMoveEvents = false;
@@ -883,11 +890,9 @@
                     mFlingScroller.forceFinished(true);
                     mAdjustScroller.forceFinished(true);
                 } else if (mLastDownEventY < mTopSelectionDividerTop) {
-                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             false, ViewConfiguration.getLongPressTimeout());
                 } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
-                    hideSoftInput();
                     postChangeCurrentByOneFromLongPress(
                             true, ViewConfiguration.getLongPressTimeout());
                 } else {
@@ -1120,6 +1125,7 @@
     @Override
     public void scrollBy(int x, int y) {
         int[] selectorIndices = mSelectorIndices;
+        int startScrollOffset = mCurrentScrollOffset;
         if (!mWrapSelectorWheel && y > 0
                 && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
             mCurrentScrollOffset = mInitialScrollOffset;
@@ -1147,6 +1153,9 @@
                 mCurrentScrollOffset = mInitialScrollOffset;
             }
         }
+        if (startScrollOffset != mCurrentScrollOffset) {
+            onScrollChanged(0, mCurrentScrollOffset, 0, startScrollOffset);
+        }
     }
 
     @Override
@@ -1735,7 +1744,10 @@
         }
         int previous = mValue;
         mValue = current;
-        updateInputTextView();
+        // If we're flinging, we'll update the text view at the end when it becomes visible
+        if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
+            updateInputTextView();
+        }
         if (notifyChange) {
             notifyChange(previous, current);
         }
@@ -1752,7 +1764,7 @@
      */
      private void changeValueByOne(boolean increment) {
         if (mHasSelectorWheel) {
-            mInputText.setVisibility(View.INVISIBLE);
+            hideSoftInput();
             if (!moveToFinalScrollerPosition(mFlingScroller)) {
                 moveToFinalScrollerPosition(mAdjustScroller);
             }
@@ -1799,9 +1811,8 @@
      */
     private void onScrollerFinished(Scroller scroller) {
         if (scroller == mFlingScroller) {
-            if (!ensureScrollWheelAdjusted()) {
-                updateInputTextView();
-            }
+            ensureScrollWheelAdjusted();
+            updateInputTextView();
             onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
         } else {
             if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
@@ -1937,9 +1948,25 @@
          */
         String text = (mDisplayedValues == null) ? formatNumber(mValue)
                 : mDisplayedValues[mValue - mMinValue];
-        if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
-            mInputText.setText(text);
-            return true;
+        if (!TextUtils.isEmpty(text)) {
+            CharSequence beforeText = mInputText.getText();
+            if (!text.equals(beforeText.toString())) {
+                mInputText.setText(text);
+                if (mAccessibilityNodeProvider != null) {
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+                    mInputText.onInitializeAccessibilityEvent(event);
+                    mInputText.onPopulateAccessibilityEvent(event);
+                    event.setFromIndex(0);
+                    event.setRemovedCount(beforeText.length());
+                    event.setAddedCount(text.length());
+                    event.setBeforeText(beforeText);
+                    event.setSource(NumberPicker.this,
+                            AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT);
+                    requestSendAccessibilityEvent(NumberPicker.this, event);
+                }
+                return true;
+            }
         }
 
         return false;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index eaf1115..bf44f62 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10136,7 +10136,11 @@
             if (lineCount <= 1) {
                 // Simple case: this is a single line.
                 final CharSequence text = getText();
-                structure.setText(text, getSelectionStart(), getSelectionEnd());
+                if (forAutofill) {
+                    structure.setText(text);
+                } else {
+                    structure.setText(text, getSelectionStart(), getSelectionEnd());
+                }
             } else {
                 // Complex case: multi-line, could be scrolled or within a scroll container
                 // so some lines are not visible.
@@ -10172,9 +10176,11 @@
                 if (expandedBottomLine >= lineCount) {
                     expandedBottomLine = lineCount - 1;
                 }
+
                 // Convert lines into character offsets.
                 int expandedTopChar = layout.getLineStart(expandedTopLine);
                 int expandedBottomChar = layout.getLineEnd(expandedBottomLine);
+
                 // Take into account selection -- if there is a selection, we need to expand
                 // the text we are returning to include that selection.
                 final int selStart = getSelectionStart();
@@ -10187,48 +10193,57 @@
                         expandedBottomChar = selEnd;
                     }
                 }
+
                 // Get the text and trim it to the range we are reporting.
                 CharSequence text = getText();
                 if (expandedTopChar > 0 || expandedBottomChar < text.length()) {
                     text = text.subSequence(expandedTopChar, expandedBottomChar);
                 }
-                structure.setText(text, selStart - expandedTopChar, selEnd - expandedTopChar);
-                final int[] lineOffsets = new int[bottomLine - topLine + 1];
-                final int[] lineBaselines = new int[bottomLine - topLine + 1];
-                final int baselineOffset = getBaselineOffset();
-                for (int i = topLine; i <= bottomLine; i++) {
-                    lineOffsets[i - topLine] = layout.getLineStart(i);
-                    lineBaselines[i - topLine] = layout.getLineBaseline(i) + baselineOffset;
+
+                if (forAutofill) {
+                    structure.setText(text);
+                } else {
+                    structure.setText(text, selStart - expandedTopChar, selEnd - expandedTopChar);
+
+                    final int[] lineOffsets = new int[bottomLine - topLine + 1];
+                    final int[] lineBaselines = new int[bottomLine - topLine + 1];
+                    final int baselineOffset = getBaselineOffset();
+                    for (int i = topLine; i <= bottomLine; i++) {
+                        lineOffsets[i - topLine] = layout.getLineStart(i);
+                        lineBaselines[i - topLine] = layout.getLineBaseline(i) + baselineOffset;
+                    }
+                    structure.setTextLines(lineOffsets, lineBaselines);
                 }
-                structure.setTextLines(lineOffsets, lineBaselines);
             }
 
-            // Extract style information that applies to the TextView as a whole.
-            int style = 0;
-            int typefaceStyle = getTypefaceStyle();
-            if ((typefaceStyle & Typeface.BOLD) != 0) {
-                style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
-            }
-            if ((typefaceStyle & Typeface.ITALIC) != 0) {
-                style |= AssistStructure.ViewNode.TEXT_STYLE_ITALIC;
-            }
+            if (!forAutofill) {
+                // Extract style information that applies to the TextView as a whole.
+                int style = 0;
+                int typefaceStyle = getTypefaceStyle();
+                if ((typefaceStyle & Typeface.BOLD) != 0) {
+                    style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+                }
+                if ((typefaceStyle & Typeface.ITALIC) != 0) {
+                    style |= AssistStructure.ViewNode.TEXT_STYLE_ITALIC;
+                }
 
-            // Global styles can also be set via TextView.setPaintFlags().
-            int paintFlags = mTextPaint.getFlags();
-            if ((paintFlags & Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
-                style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
-            }
-            if ((paintFlags & Paint.UNDERLINE_TEXT_FLAG) != 0) {
-                style |= AssistStructure.ViewNode.TEXT_STYLE_UNDERLINE;
-            }
-            if ((paintFlags & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
-                style |= AssistStructure.ViewNode.TEXT_STYLE_STRIKE_THRU;
-            }
+                // Global styles can also be set via TextView.setPaintFlags().
+                int paintFlags = mTextPaint.getFlags();
+                if ((paintFlags & Paint.FAKE_BOLD_TEXT_FLAG) != 0) {
+                    style |= AssistStructure.ViewNode.TEXT_STYLE_BOLD;
+                }
+                if ((paintFlags & Paint.UNDERLINE_TEXT_FLAG) != 0) {
+                    style |= AssistStructure.ViewNode.TEXT_STYLE_UNDERLINE;
+                }
+                if ((paintFlags & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
+                    style |= AssistStructure.ViewNode.TEXT_STYLE_STRIKE_THRU;
+                }
 
-            // TextView does not have its own text background color. A background is either part
-            // of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
-            structure.setTextStyle(getTextSize(), getCurrentTextColor(),
-                    AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
+                // TextView does not have its own text background color. A background is either part
+                // of the View (and can be any drawable) or a BackgroundColorSpan inside the text.
+                structure.setTextStyle(getTextSize(), getCurrentTextColor(),
+                        AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
+            }
         }
         structure.setHint(getHint());
         structure.setInputType(getInputType());
@@ -10385,14 +10400,13 @@
                     positionInfoStartIndex + positionInfoLength,
                     viewportToContentHorizontalOffset(), viewportToContentVerticalOffset());
             CursorAnchorInfo cursorAnchorInfo = builder.setMatrix(null).build();
-            int[] locationOnScreen = getLocationOnScreen();
             for (int i = 0; i < positionInfoLength; i++) {
                 int flags = cursorAnchorInfo.getCharacterBoundsFlags(positionInfoStartIndex + i);
                 if ((flags & FLAG_HAS_VISIBLE_REGION) == FLAG_HAS_VISIBLE_REGION) {
                     RectF bounds = cursorAnchorInfo
                             .getCharacterBounds(positionInfoStartIndex + i);
                     if (bounds != null) {
-                        bounds.offset(locationOnScreen[0], locationOnScreen[1]);
+                        mapRectFromViewToScreenCoords(bounds, true);
                         boundingRects[i] = bounds;
                     }
                 }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 99a25fd..373f4bb 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -132,6 +132,7 @@
     void noteBleScanStarted(in WorkSource ws);
     void noteBleScanStopped(in WorkSource ws);
     void noteResetBleScan();
+    void noteBleScanResult(in WorkSource ws);
 
     HealthStatsParceler takeUidSnapshot(int uid);
     HealthStatsParceler[] takeUidSnapshots(in int[] uid);
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 0b27c60..398d087 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -16,16 +16,14 @@
 
 package com.android.internal.app;
 
-import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
-
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -34,8 +32,12 @@
 import android.util.Slog;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.List;
 
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+
 /**
  * This is used in conjunction with
  * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to
@@ -51,15 +53,17 @@
     public static String FORWARD_INTENT_TO_MANAGED_PROFILE
             = "com.android.internal.app.ForwardIntentToManagedProfile";
 
+    private Injector mInjector;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Intent intentReceived = getIntent();
+        mInjector = createInjector();
 
+        Intent intentReceived = getIntent();
         String className = intentReceived.getComponent().getClassName();
         final int targetUserId;
         final int userMessageId;
-
         if (className.equals(FORWARD_INTENT_TO_PARENT)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_owner;
             targetUserId = getProfileParent();
@@ -76,17 +80,12 @@
             finish();
             return;
         }
-        Intent newIntent = new Intent(intentReceived);
-        newIntent.setComponent(null);
-        // Apps should not be allowed to target a specific package in the target user.
-        newIntent.setPackage(null);
-        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
-                |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
-        int callingUserId = getUserId();
 
-        if (canForward(newIntent, targetUserId)) {
+        final int callingUserId = getUserId();
+        final Intent newIntent = canForward(intentReceived, targetUserId);
+        if (newIntent != null) {
             if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) {
-                Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+                Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
                 // At this point, innerIntent is not null. Otherwise, canForward would have returned
                 // false.
                 innerIntent.prepareToLeaveUser(callingUserId);
@@ -94,15 +93,18 @@
                 newIntent.prepareToLeaveUser(callingUserId);
             }
 
-            final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
-                        newIntent, MATCH_DEFAULT_ONLY, targetUserId);
+            final android.content.pm.ResolveInfo ri =
+                    mInjector.getPackageManager().resolveActivityAsUser(
+                            newIntent,
+                            MATCH_DEFAULT_ONLY,
+                            targetUserId);
 
             // Don't show the disclosure if next activity is ResolverActivity or ChooserActivity
             // as those will already have shown work / personal as neccesary etc.
             final boolean shouldShowDisclosure = ri == null || ri.activityInfo == null ||
                     !"android".equals(ri.activityInfo.packageName) ||
                     !(ResolverActivity.class.getName().equals(ri.activityInfo.name)
-                    || ChooserActivity.class.getName().equals(ri.activityInfo.name));
+                            || ChooserActivity.class.getName().equals(ri.activityInfo.name));
 
             try {
                 startActivityAsCaller(newIntent, null, false, targetUserId);
@@ -126,44 +128,56 @@
                 Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
             }
         } else {
-            Slog.wtf(TAG, "the intent: " + newIntent + " cannot be forwarded from user "
+            Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
                     + callingUserId + " to user " + targetUserId);
         }
         finish();
     }
 
-    boolean canForward(Intent intent, int targetUserId)  {
-        IPackageManager ipm = AppGlobals.getPackageManager();
-        if (Intent.ACTION_CHOOSER.equals(intent.getAction())) {
+    /**
+     * Check whether the intent can be forwarded to target user. Return the intent used for
+     * forwarding if it can be forwarded, {@code null} otherwise.
+     */
+    Intent canForward(Intent incomingIntent, int targetUserId)  {
+        Intent forwardIntent = new Intent(incomingIntent);
+        forwardIntent.addFlags(
+                Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+        sanitizeIntent(forwardIntent);
+
+        Intent intentToCheck = forwardIntent;
+        if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) {
             // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
-            if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
                 Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
                         + " a different user");
-                return false;
+                return null;
             }
-            if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
+            if (forwardIntent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
                 Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
                         + " different user");
-                return false;
+                return null;
             }
-            intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
-            if (intent == null) {
+            intentToCheck = forwardIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+            if (intentToCheck == null) {
                 Slog.wtf(TAG, "Cannot forward a chooser intent with no extra "
                         + Intent.EXTRA_INTENT);
-                return false;
+                return null;
             }
         }
-        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
-        if (intent.getSelector() != null) {
-            intent = intent.getSelector();
+        if (forwardIntent.getSelector() != null) {
+            intentToCheck = forwardIntent.getSelector();
         }
+        String resolvedType = intentToCheck.resolveTypeIfNeeded(getContentResolver());
+        sanitizeIntent(intentToCheck);
         try {
-            return ipm.canForwardTo(intent, resolvedType, getUserId(),
-                    targetUserId);
+            if (mInjector.getIPackageManager().
+                    canForwardTo(intentToCheck, resolvedType, getUserId(), targetUserId)) {
+                return forwardIntent;
+            }
         } catch (RemoteException e) {
             Slog.e(TAG, "PackageManagerService is dead?");
-            return false;
         }
+        return null;
     }
 
     /**
@@ -174,8 +188,7 @@
      * on the device.
      */
     private int getManagedProfile() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.myUserId());
+        List<UserInfo> relatedUsers = mInjector.getUserManager().getProfiles(UserHandle.myUserId());
         for (UserInfo userInfo : relatedUsers) {
             if (userInfo.isManagedProfile()) return userInfo.id;
         }
@@ -189,8 +202,7 @@
      * no parent.
      */
     private int getProfileParent() {
-        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        UserInfo parent = userManager.getProfileParent(UserHandle.myUserId());
+        UserInfo parent = mInjector.getUserManager().getProfileParent(UserHandle.myUserId());
         if (parent == null) {
             Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT
                     + " has been called, but there is no parent");
@@ -198,4 +210,44 @@
         }
         return parent.id;
     }
+
+    /**
+     * Sanitize the intent in place.
+     */
+    private void sanitizeIntent(Intent intent) {
+        // Apps should not be allowed to target a specific package/ component in the target user.
+        intent.setPackage(null);
+        intent.setComponent(null);
+    }
+
+    @VisibleForTesting
+    protected Injector createInjector() {
+        return new InjectorImpl();
+    }
+
+    private class InjectorImpl implements Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return AppGlobals.getPackageManager();
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return getSystemService(UserManager.class);
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return IntentForwarderActivity.this.getPackageManager();
+        }
+    }
+
+    public interface Injector {
+        IPackageManager getIPackageManager();
+
+        UserManager getUserManager();
+
+        PackageManager getPackageManager();
+    }
 }
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 506114b..3d3e148 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -50,6 +50,11 @@
     private static final boolean USE_NATIVE_PARSING = true;
     private static final boolean SANITY_CHECK_NATIVE = false;
 
+    private static final String CLATD_INTERFACE_PREFIX = "v4-";
+    // Delta between IPv4 header (20b) and IPv6 header (40b).
+    // Used for correct stats accounting on clatd interfaces.
+    private static final int IPV4V6_HEADER_DELTA = 20;
+
     /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
     private final File mStatsXtIfaceAll;
     /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */
@@ -57,6 +62,7 @@
     /** Path to {@code /proc/net/xt_qtaguid/stats}. */
     private final File mStatsXtUid;
 
+    // TODO: to improve testability and avoid global state, do not use a static variable.
     @GuardedBy("sStackedIfaces")
     private static final ArrayMap<String, String> sStackedIfaces = new ArrayMap<>();
 
@@ -124,9 +130,7 @@
                 stats.addValues(entry);
                 reader.finishLine();
             }
-        } catch (NullPointerException e) {
-            throw new ProtocolException("problem parsing stats", e);
-        } catch (NumberFormatException e) {
+        } catch (NullPointerException|NumberFormatException e) {
             throw new ProtocolException("problem parsing stats", e);
         } finally {
             IoUtils.closeQuietly(reader);
@@ -171,9 +175,7 @@
                 stats.addValues(entry);
                 reader.finishLine();
             }
-        } catch (NullPointerException e) {
-            throw new ProtocolException("problem parsing stats", e);
-        } catch (NumberFormatException e) {
+        } catch (NullPointerException|NumberFormatException e) {
             throw new ProtocolException("problem parsing stats", e);
         } finally {
             IoUtils.closeQuietly(reader);
@@ -188,48 +190,54 @@
 
     public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag,
             NetworkStats lastStats) throws IOException {
-        final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag,
-                lastStats);
-
+        final NetworkStats stats =
+              readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats);
+        final ArrayMap<String, String> stackedIfaces;
         synchronized (sStackedIfaces) {
-            // Sigh, xt_qtaguid ends up double-counting tx traffic going through
-            // clatd interfaces, so we need to subtract it here.
-            final int size = sStackedIfaces.size();
-            for (int i = 0; i < size; i++) {
-                final String stackedIface = sStackedIfaces.keyAt(i);
-                final String baseIface = sStackedIfaces.valueAt(i);
-
-                // Count up the tx traffic and subtract from root UID on the
-                // base interface.
-                NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L,
-                        0L, 0L);
-                NetworkStats.Entry entry = null;
-                for (int j = 0; j < stats.size(); j++) {
-                    entry = stats.getValues(j, entry);
-                    if (Objects.equals(entry.iface, stackedIface)) {
-                        adjust.txBytes -= entry.txBytes;
-                        adjust.txPackets -= entry.txPackets;
-                    }
-                }
-                stats.combineValues(adjust);
-            }
+            stackedIfaces = new ArrayMap<>(sStackedIfaces);
         }
+        // Total 464xlat traffic to subtract from uid 0 on all base interfaces.
+        final NetworkStats adjustments = new NetworkStats(0, stackedIfaces.size());
 
-        // Double sigh, all rx traffic on clat needs to be tweaked to
-        // account for the dropped IPv6 header size post-unwrap.
-        NetworkStats.Entry entry = null;
+        NetworkStats.Entry entry = null; // For recycling
+
+        // For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4
+        // packet on the stacked interface, and once as translated to an IPv6 packet on the
+        // base interface. For correct stats accounting on the base interface, every 464xlat
+        // packet needs to be subtracted from the root UID on the base interface both for tx
+        // and rx traffic (http://b/12249687, http:/b/33681750).
         for (int i = 0; i < stats.size(); i++) {
             entry = stats.getValues(i, entry);
-            if (entry.iface != null && entry.iface.startsWith("clat")) {
-                // Delta between IPv4 header (20b) and IPv6 header (40b)
-                entry.rxBytes = entry.rxPackets * 20;
-                entry.rxPackets = 0;
-                entry.txBytes = 0;
-                entry.txPackets = 0;
-                stats.combineValues(entry);
+            if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) {
+                continue;
             }
+            final String baseIface = stackedIfaces.get(entry.iface);
+            if (baseIface == null) {
+                continue;
+            }
+
+            NetworkStats.Entry adjust =
+                    new NetworkStats.Entry(baseIface, 0, 0, 0, 0L, 0L, 0L, 0L, 0L);
+            // Subtract any 464lat traffic seen for the root UID on the current base interface.
+            adjust.rxBytes -= (entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA);
+            adjust.txBytes -= (entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA);
+            adjust.rxPackets -= entry.rxPackets;
+            adjust.txPackets -= entry.txPackets;
+            adjustments.combineValues(adjust);
+
+            // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent
+            // on the stacked interface with prefix "v4-" and drops the IPv6 header size after
+            // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes
+            // difference for all packets (http://b/12249687, http:/b/33681750).
+            entry.rxBytes = entry.rxPackets * IPV4V6_HEADER_DELTA;
+            entry.txBytes = entry.txPackets * IPV4V6_HEADER_DELTA;
+            entry.rxPackets = 0;
+            entry.txPackets = 0;
+            stats.combineValues(entry);
         }
 
+        stats.combineAllValues(adjustments);
+
         return stats;
     }
 
@@ -305,9 +313,7 @@
 
                 reader.finishLine();
             }
-        } catch (NullPointerException e) {
-            throw new ProtocolException("problem parsing idx " + idx, e);
-        } catch (NumberFormatException e) {
+        } catch (NullPointerException|NumberFormatException e) {
             throw new ProtocolException("problem parsing idx " + idx, e);
         } finally {
             IoUtils.closeQuietly(reader);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index a582c2c..748272600 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -114,7 +114,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 155 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 156 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -4704,6 +4704,14 @@
         }
     }
 
+    public void noteBluetoothScanResultFromSourceLocked(WorkSource ws) {
+        final int N = ws.size();
+        for (int i = 0; i < N; i++) {
+            int uid = mapUid(ws.get(i));
+            getUidStatsLocked(uid).noteBluetoothScanResultLocked();
+        }
+    }
+
     private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
             final long uptimeMillis, int uid) {
         uid = mapUid(uid);
@@ -5421,6 +5429,7 @@
         StopwatchTimer mCameraTurnedOnTimer;
         StopwatchTimer mForegroundActivityTimer;
         DualTimer mBluetoothScanTimer;
+        Counter mBluetoothScanResultCounter;
 
         int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
         StopwatchTimer[] mProcessStateTimer;
@@ -5864,6 +5873,17 @@
             }
         }
 
+        public Counter createBluetoothScanResultCounterLocked() {
+            if (mBluetoothScanResultCounter == null) {
+                mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase);
+            }
+            return mBluetoothScanResultCounter;
+        }
+
+        public void noteBluetoothScanResultLocked() {
+            createBluetoothScanResultCounterLocked().stepAtomic();
+        }
+
         @Override
         public void noteActivityResumedLocked(long elapsedRealtimeMs) {
             // We always start, since we want multiple foreground PIDs to nest
@@ -6017,6 +6037,11 @@
             return mBluetoothScanTimer.getSubTimer();
         }
 
+        @Override
+        public Counter getBluetoothScanResultCounter() {
+            return mBluetoothScanResultCounter;
+        }
+
         void makeProcessState(int i, Parcel in) {
             if (i < 0 || i >= NUM_PROCESS_STATE) return;
 
@@ -6266,6 +6291,9 @@
             active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
             active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
             active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
+            if (mBluetoothScanResultCounter != null) {
+                mBluetoothScanResultCounter.reset(false);
+            }
 
             if (mProcessStateTimer != null) {
                 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
@@ -6450,6 +6478,10 @@
                     mBluetoothScanTimer.detach();
                     mBluetoothScanTimer = null;
                 }
+                if (mBluetoothScanResultCounter != null) {
+                    mBluetoothScanResultCounter.detach();
+                    mBluetoothScanResultCounter = null;
+                }
                 if (mUserActivityCounters != null) {
                     for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
                         mUserActivityCounters[i].detach();
@@ -6620,6 +6652,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (mBluetoothScanResultCounter != null) {
+                out.writeInt(1);
+                mBluetoothScanResultCounter.writeToParcel(out);
+            } else {
+                out.writeInt(0);
+            }
             for (int i = 0; i < NUM_PROCESS_STATE; i++) {
                 if (mProcessStateTimer[i] != null) {
                     out.writeInt(1);
@@ -6850,6 +6888,11 @@
             } else {
                 mBluetoothScanTimer = null;
             }
+            if (in.readInt() != 0) {
+                mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
+            } else {
+                mBluetoothScanResultCounter = null;
+            }
             mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
             for (int i = 0; i < NUM_PROCESS_STATE; i++) {
                 if (in.readInt() != 0) {
@@ -10998,6 +11041,9 @@
             if (in.readInt() != 0) {
                 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
             }
+            if (in.readInt() != 0) {
+                u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
+            }
             u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
             for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
                 if (in.readInt() != 0) {
@@ -11391,6 +11437,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (u.mBluetoothScanResultCounter != null) {
+                out.writeInt(1);
+                u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
+            } else {
+                out.writeInt(0);
+            }
             for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
                 if (u.mProcessStateTimer[i] != null) {
                     out.writeInt(1);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 80b6b08..1b83708 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1498,7 +1498,6 @@
 
         final Window.Callback cb = mWindow.getCallback();
         if (cb != null && !mWindow.isDestroyed() && mFeatureId < 0) {
-            cb.onBeforeAttachedToWindow();
             cb.onAttachedToWindow();
         }
 
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 73886a7..91bc681 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -583,4 +583,8 @@
         }
         return size - leftIdx;
     }
+
+    public static @NonNull String[] defeatNullable(@Nullable String[] val) {
+        return (val != null) ? val : EmptyArray.STRING;
+    }
 }
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 2c97f8b..cd41f9e 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -286,6 +286,38 @@
     }
 
     /**
+     * Finds a suitable alpha such that there's enough contrast.
+     *
+     * @param color the color to start searching from.
+     * @param backgroundColor the color to ensure contrast against.
+     * @param minRatio the minimum contrast ratio required.
+     * @return the same color as {@param color} with potentially modified alpha to meet contrast
+     */
+    public static int findAlphaToMeetContrast(int color, int backgroundColor, double minRatio) {
+        int fg = color;
+        int bg = backgroundColor;
+        if (ColorUtilsFromCompat.calculateContrast(fg, bg) >= minRatio) {
+            return color;
+        }
+        int startAlpha = Color.alpha(color);
+        int r = Color.red(color);
+        int g = Color.green(color);
+        int b = Color.blue(color);
+
+        int low = startAlpha, high = 255;
+        for (int i = 0; i < 15 && high - low > 0; i++) {
+            final int alpha = (low + high) / 2;
+            fg = Color.argb(alpha, r, g, b);
+            if (ColorUtilsFromCompat.calculateContrast(fg, bg) > minRatio) {
+                high = alpha;
+            } else {
+                low = alpha;
+            }
+        }
+        return Color.argb(high, r, g, b);
+    }
+
+    /**
      * Finds a suitable color such that there's enough contrast.
      *
      * @param color the color to start searching from.
@@ -373,19 +405,19 @@
      * color for the Notification's action and header text.
      *
      * @param notificationColor the color of the notification or {@link Notification#COLOR_DEFAULT}
+     * @param backgroundColor the background color to ensure the contrast against.
      * @return a color of the same hue with enough contrast against the backgrounds.
      */
-    public static int resolveContrastColor(Context context, int notificationColor) {
+    public static int resolveContrastColor(Context context, int notificationColor,
+            int backgroundColor) {
         final int resolvedColor = resolveColor(context, notificationColor);
 
         final int actionBg = context.getColor(
                 com.android.internal.R.color.notification_action_list);
-        final int notiBg = context.getColor(
-                com.android.internal.R.color.notification_material_background_color);
 
         int color = resolvedColor;
         color = NotificationColorUtil.ensureLargeTextContrast(color, actionBg);
-        color = NotificationColorUtil.ensureTextContrast(color, notiBg);
+        color = NotificationColorUtil.ensureTextContrast(color, backgroundColor);
 
         if (color != resolvedColor) {
             if (DEBUG){
@@ -394,7 +426,7 @@
                                 + " and %s (over background) by changing #%s to %s",
                         context.getPackageName(),
                         NotificationColorUtil.contrastChange(resolvedColor, color, actionBg),
-                        NotificationColorUtil.contrastChange(resolvedColor, color, notiBg),
+                        NotificationColorUtil.contrastChange(resolvedColor, color, backgroundColor),
                         Integer.toHexString(resolvedColor), Integer.toHexString(color)));
             }
         }
@@ -502,6 +534,13 @@
     }
 
     /**
+     * Composite two potentially translucent colors over each other and returns the result.
+     */
+    public static int compositeColors(int foreground, int background) {
+        return ColorUtilsFromCompat.compositeColors(foreground, background);
+    }
+
+    /**
      * Framework copy of functions needed from android.support.v4.graphics.ColorUtils.
      */
     private static class ColorUtilsFromCompat {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
new file mode 100644
index 0000000..0dc46ed
--- /dev/null
+++ b/core/jni/Android.bp
@@ -0,0 +1,286 @@
+cc_library_shared {
+    name: "libandroid_runtime",
+
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wno-non-virtual-dtor",
+        "-Wno-maybe-uninitialized",
+        "-Wno-parentheses",
+
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+
+        "-DU_USING_ICU_NAMESPACE=0",
+
+        "-Wall",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wunused",
+        "-Wunreachable-code",
+
+        // necessary for Clang as the GL bindings need to turn
+        // off a GCC warning that Clang doesn't know.
+        "-Wno-unknown-pragmas",
+
+        // TODO: Linear blending should be enabled by default, but we are
+        // TODO: making it an opt-in while it's a work in progress
+        //"-DANDROID_ENABLE_LINEAR_BLENDING",
+    ],
+
+    cppflags: ["-Wno-conversion-null"],
+
+    srcs: [
+        "AndroidRuntime.cpp",
+        "com_android_internal_content_NativeLibraryHelper.cpp",
+        "com_google_android_gles_jni_EGLImpl.cpp",
+        "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
+        "android_app_Activity.cpp",
+        "android_app_ApplicationLoaders.cpp",
+        "android_app_NativeActivity.cpp",
+        "android_app_admin_SecurityLog.cpp",
+        "android_opengl_EGL14.cpp",
+        "android_opengl_EGLExt.cpp",
+        "android_opengl_GLES10.cpp",
+        "android_opengl_GLES10Ext.cpp",
+        "android_opengl_GLES11.cpp",
+        "android_opengl_GLES11Ext.cpp",
+        "android_opengl_GLES20.cpp",
+        "android_opengl_GLES30.cpp",
+        "android_opengl_GLES31.cpp",
+        "android_opengl_GLES31Ext.cpp",
+        "android_opengl_GLES32.cpp",
+        "android_database_CursorWindow.cpp",
+        "android_database_SQLiteCommon.cpp",
+        "android_database_SQLiteConnection.cpp",
+        "android_database_SQLiteGlobal.cpp",
+        "android_database_SQLiteDebug.cpp",
+        "android_graphics_drawable_AnimatedVectorDrawable.cpp",
+        "android_graphics_drawable_VectorDrawable.cpp",
+        "android_view_DisplayEventReceiver.cpp",
+        "android_view_DisplayListCanvas.cpp",
+        "android_view_HardwareLayer.cpp",
+        "android_view_InputChannel.cpp",
+        "android_view_InputDevice.cpp",
+        "android_view_InputEventReceiver.cpp",
+        "android_view_InputEventSender.cpp",
+        "android_view_InputQueue.cpp",
+        "android_view_KeyCharacterMap.cpp",
+        "android_view_KeyEvent.cpp",
+        "android_view_MotionEvent.cpp",
+        "android_view_PointerIcon.cpp",
+        "android_view_RenderNode.cpp",
+        "android_view_RenderNodeAnimator.cpp",
+        "android_view_Surface.cpp",
+        "android_view_SurfaceControl.cpp",
+        "android_view_SurfaceSession.cpp",
+        "android_view_TextureView.cpp",
+        "android_view_ThreadedRenderer.cpp",
+        "android_view_VelocityTracker.cpp",
+        "android_text_AndroidCharacter.cpp",
+        "android_text_AndroidBidi.cpp",
+        "android_text_StaticLayout.cpp",
+        "android_os_Debug.cpp",
+        "android_os_GraphicsEnvironment.cpp",
+        "android_os_HwBinder.cpp",
+        "android_os_HwBlob.cpp",
+        "android_os_HwParcel.cpp",
+        "android_os_HwRemoteBinder.cpp",
+        "android_os_MemoryFile.cpp",
+        "android_os_MessageQueue.cpp",
+        "android_os_Parcel.cpp",
+        "android_os_SELinux.cpp",
+        "android_os_seccomp.cpp",
+        "android_os_SystemClock.cpp",
+        "android_os_SystemProperties.cpp",
+        "android_os_Trace.cpp",
+        "android_os_UEventObserver.cpp",
+        "android_os_VintfObject.cpp",
+        "android_os_VintfRuntimeInfo.cpp",
+        "android_net_LocalSocketImpl.cpp",
+        "android_net_NetUtils.cpp",
+        "android_net_TrafficStats.cpp",
+        "android_nio_utils.cpp",
+        "android_util_AssetManager.cpp",
+        "android_util_Binder.cpp",
+        "android_util_EventLog.cpp",
+        "android_util_MemoryIntArray.cpp",
+        "android_util_Log.cpp",
+        "android_util_PathParser.cpp",
+        "android_util_Process.cpp",
+        "android_util_StringBlock.cpp",
+        "android_util_XmlBlock.cpp",
+        "android_util_jar_StrictJarFile.cpp",
+        "android_graphics_Canvas.cpp",
+        "android_graphics_Picture.cpp",
+        "android/graphics/Bitmap.cpp",
+        "android/graphics/BitmapFactory.cpp",
+        "android/graphics/Camera.cpp",
+        "android/graphics/CanvasProperty.cpp",
+        "android/graphics/ColorFilter.cpp",
+        "android/graphics/DrawFilter.cpp",
+        "android/graphics/FontFamily.cpp",
+        "android/graphics/FontUtils.cpp",
+        "android/graphics/CreateJavaOutputStreamAdaptor.cpp",
+        "android/graphics/GIFMovie.cpp",
+        "android/graphics/GraphicBuffer.cpp",
+        "android/graphics/Graphics.cpp",
+        "android/graphics/HarfBuzzNGFaceSkia.cpp",
+        "android/graphics/Interpolator.cpp",
+        "android/graphics/MaskFilter.cpp",
+        "android/graphics/Matrix.cpp",
+        "android/graphics/Movie.cpp",
+        "android/graphics/MovieImpl.cpp",
+        "android/graphics/NinePatch.cpp",
+        "android/graphics/NinePatchPeeker.cpp",
+        "android/graphics/Paint.cpp",
+        "android/graphics/Path.cpp",
+        "android/graphics/PathMeasure.cpp",
+        "android/graphics/PathEffect.cpp",
+        "android/graphics/Picture.cpp",
+        "android/graphics/BitmapRegionDecoder.cpp",
+        "android/graphics/Region.cpp",
+        "android/graphics/Shader.cpp",
+        "android/graphics/SurfaceTexture.cpp",
+        "android/graphics/Typeface.cpp",
+        "android/graphics/Utils.cpp",
+        "android/graphics/YuvToJpegEncoder.cpp",
+        "android/graphics/pdf/PdfDocument.cpp",
+        "android/graphics/pdf/PdfEditor.cpp",
+        "android/graphics/pdf/PdfRenderer.cpp",
+        "android/graphics/pdf/PdfUtils.cpp",
+        "android_media_AudioRecord.cpp",
+        "android_media_AudioSystem.cpp",
+        "android_media_AudioTrack.cpp",
+        "android_media_DeviceCallback.cpp",
+        "android_media_JetPlayer.cpp",
+        "android_media_RemoteDisplay.cpp",
+        "android_media_ToneGenerator.cpp",
+        "android_hardware_Camera.cpp",
+        "android_hardware_camera2_CameraMetadata.cpp",
+        "android_hardware_camera2_legacy_LegacyCameraDevice.cpp",
+        "android_hardware_camera2_legacy_PerfMeasurement.cpp",
+        "android_hardware_camera2_DngCreator.cpp",
+        "android_hardware_HardwareBuffer.cpp",
+        "android_hardware_Radio.cpp",
+        "android_hardware_SensorManager.cpp",
+        "android_hardware_SerialPort.cpp",
+        "android_hardware_SoundTrigger.cpp",
+        "android_hardware_UsbDevice.cpp",
+        "android_hardware_UsbDeviceConnection.cpp",
+        "android_hardware_UsbRequest.cpp",
+        "android_hardware_location_ActivityRecognitionHardware.cpp",
+        "android_util_FileObserver.cpp",
+        "android/opengl/poly_clip.cpp", // TODO: .arm
+        "android/opengl/util.cpp",
+        "android_server_NetworkManagementSocketTagger.cpp",
+        "android_server_Watchdog.cpp",
+        "android_ddm_DdmHandleNativeHeap.cpp",
+        "android_backup_BackupDataInput.cpp",
+        "android_backup_BackupDataOutput.cpp",
+        "android_backup_FileBackupHelperBase.cpp",
+        "android_backup_BackupHelperDispatcher.cpp",
+        "android_app_backup_FullBackup.cpp",
+        "android_content_res_ObbScanner.cpp",
+        "android_content_res_Configuration.cpp",
+        "android_animation_PropertyValuesHolder.cpp",
+        "com_android_internal_net_NetworkStatsFactory.cpp",
+        "com_android_internal_os_FuseAppLoop.cpp",
+        "com_android_internal_os_PathClassLoaderFactory.cpp",
+        "com_android_internal_os_Zygote.cpp",
+        "com_android_internal_util_VirtualRefBasePtr.cpp",
+        "com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
+        "hwbinder/EphemeralStorage.cpp",
+        "fd_utils.cpp",
+    ],
+
+    include_dirs: [
+        // we need to access the private Bionic header
+        // <bionic_tls.h> in com_google_android_gles_jni_GLImpl.cpp
+        "bionic/libc/private",
+
+        "external/skia/include/private",
+        "external/skia/src/codec",
+        "external/skia/src/core",
+        "external/skia/src/effects",
+        "external/skia/src/image",
+        "external/skia/src/images",
+        "frameworks/base/media/jni",
+        "libcore/include",
+        "system/media/camera/include",
+        "system/media/private/camera/include",
+    ],
+
+    static_libs: [
+        "libgif",
+        "libseccomp_policy",
+        "libselinux",
+        "libcrypto",
+        "libgrallocusage",
+    ],
+
+    shared_libs: [
+        "libmemtrack",
+        "libandroidfw",
+        "libappfuse",
+        "libbase",
+        "libnativehelper",
+        "liblog",
+        "libcutils",
+        "libdebuggerd_client",
+        "libutils",
+        "libbinder",
+        "libui",
+        "libgui",
+        "libsensor",
+        "libinput",
+        "libcamera_client",
+        "libcamera_metadata",
+        "libskia",
+        "libsqlite",
+        "libEGL",
+        "libGLESv1_CM",
+        "libGLESv2",
+        "libvulkan",
+        "libziparchive",
+        "libETC1",
+        "libhardware",
+        "libhardware_legacy",
+        "libselinux",
+        "libicuuc",
+        "libmedia",
+        "libaudioclient",
+        "libjpeg",
+        "libusbhost",
+        "libharfbuzz_ng",
+        "libz",
+        "libpdfium",
+        "libimg_utils",
+        "libnetd_client",
+        "libradio",
+        "libsoundtrigger",
+        "libminikin",
+        "libprocessgroup",
+        "libnativebridge",
+        "libradio_metadata",
+        "libnativeloader",
+        "libmemunreachable",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libvintf",
+        "libnativewindow",
+
+        "libhwui",
+        "libdl",
+    ],
+
+    local_include_dirs: ["android/graphics"],
+    export_include_dirs: ["include"],
+    export_shared_lib_headers: [
+        // AndroidRuntime.h depends on nativehelper/jni.h
+        "libnativehelper",
+
+        // our headers include libnativewindow's public headers
+        "libnativewindow",
+    ],
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
deleted file mode 100644
index 77c72eb..0000000
--- a/core/jni/Android.mk
+++ /dev/null
@@ -1,322 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS += -DHAVE_CONFIG_H -DKHTML_NO_EXCEPTIONS -DGKWQ_NO_JAVA
-LOCAL_CFLAGS += -DNO_SUPPORT_JS_BINDING -DQT_NO_WHEELEVENT -DKHTML_NO_XBL
-LOCAL_CFLAGS += -U__APPLE__
-LOCAL_CFLAGS += -Wno-unused-parameter
-LOCAL_CFLAGS += -Wno-non-virtual-dtor
-LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
-LOCAL_CPPFLAGS += -Wno-conversion-null
-
-ifeq ($(TARGET_ARCH), arm)
-    LOCAL_CFLAGS += -DPACKED="__attribute__ ((packed))"
-else
-    LOCAL_CFLAGS += -DPACKED=""
-endif
-
-ifneq ($(ENABLE_CPUSETS),)
-    LOCAL_CFLAGS += -DENABLE_CPUSETS
-endif
-
-# TODO: Linear blending should be enabled by default, but we are
-# TODO: making it an opt-in while it's a work in progress
-# TODO: The final test should be:
-# TODO: ifneq ($(TARGET_ENABLE_LINEAR_BLENDING),false)
-ifeq ($(TARGET_ENABLE_LINEAR_BLENDING),true)
-    LOCAL_CFLAGS += -DANDROID_ENABLE_LINEAR_BLENDING
-endif
-
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-
-LOCAL_CFLAGS += -DU_USING_ICU_NAMESPACE=0
-
-LOCAL_SRC_FILES:= \
-    AndroidRuntime.cpp \
-    com_android_internal_content_NativeLibraryHelper.cpp \
-    com_google_android_gles_jni_EGLImpl.cpp \
-    com_google_android_gles_jni_GLImpl.cpp.arm \
-    android_app_Activity.cpp \
-    android_app_ApplicationLoaders.cpp \
-    android_app_NativeActivity.cpp \
-    android_app_admin_SecurityLog.cpp \
-    android_opengl_EGL14.cpp \
-    android_opengl_EGLExt.cpp \
-    android_opengl_GLES10.cpp \
-    android_opengl_GLES10Ext.cpp \
-    android_opengl_GLES11.cpp \
-    android_opengl_GLES11Ext.cpp \
-    android_opengl_GLES20.cpp \
-    android_opengl_GLES30.cpp \
-    android_opengl_GLES31.cpp \
-    android_opengl_GLES31Ext.cpp \
-    android_opengl_GLES32.cpp \
-    android_database_CursorWindow.cpp \
-    android_database_SQLiteCommon.cpp \
-    android_database_SQLiteConnection.cpp \
-    android_database_SQLiteGlobal.cpp \
-    android_database_SQLiteDebug.cpp \
-    android_graphics_drawable_AnimatedVectorDrawable.cpp \
-    android_graphics_drawable_VectorDrawable.cpp \
-    android_view_DisplayEventReceiver.cpp \
-    android_view_DisplayListCanvas.cpp \
-    android_view_HardwareLayer.cpp \
-    android_view_InputChannel.cpp \
-    android_view_InputDevice.cpp \
-    android_view_InputEventReceiver.cpp \
-    android_view_InputEventSender.cpp \
-    android_view_InputQueue.cpp \
-    android_view_KeyCharacterMap.cpp \
-    android_view_KeyEvent.cpp \
-    android_view_MotionEvent.cpp \
-    android_view_PointerIcon.cpp \
-    android_view_RenderNode.cpp \
-    android_view_RenderNodeAnimator.cpp \
-    android_view_Surface.cpp \
-    android_view_SurfaceControl.cpp \
-    android_view_SurfaceSession.cpp \
-    android_view_TextureView.cpp \
-    android_view_ThreadedRenderer.cpp \
-    android_view_VelocityTracker.cpp \
-    android_text_AndroidCharacter.cpp \
-    android_text_AndroidBidi.cpp \
-    android_text_StaticLayout.cpp \
-    android_os_Debug.cpp \
-    android_os_GraphicsEnvironment.cpp \
-    android_os_HwBinder.cpp \
-    android_os_HwBlob.cpp \
-    android_os_HwParcel.cpp \
-    android_os_HwRemoteBinder.cpp \
-    android_os_MemoryFile.cpp \
-    android_os_MessageQueue.cpp \
-    android_os_Parcel.cpp \
-    android_os_SELinux.cpp \
-    android_os_seccomp.cpp \
-    android_os_SystemClock.cpp \
-    android_os_SystemProperties.cpp \
-    android_os_Trace.cpp \
-    android_os_UEventObserver.cpp \
-    android_os_VintfObject.cpp \
-    android_os_VintfRuntimeInfo.cpp \
-    android_net_LocalSocketImpl.cpp \
-    android_net_NetUtils.cpp \
-    android_net_TrafficStats.cpp \
-    android_nio_utils.cpp \
-    android_util_AssetManager.cpp \
-    android_util_Binder.cpp \
-    android_util_EventLog.cpp \
-    android_util_MemoryIntArray.cpp \
-    android_util_Log.cpp \
-    android_util_PathParser.cpp \
-    android_util_Process.cpp \
-    android_util_StringBlock.cpp \
-    android_util_XmlBlock.cpp \
-    android_util_jar_StrictJarFile.cpp \
-    android_graphics_Canvas.cpp \
-    android_graphics_Picture.cpp \
-    android/graphics/Bitmap.cpp \
-    android/graphics/BitmapFactory.cpp \
-    android/graphics/Camera.cpp \
-    android/graphics/CanvasProperty.cpp \
-    android/graphics/ColorFilter.cpp \
-    android/graphics/DrawFilter.cpp \
-    android/graphics/FontFamily.cpp \
-    android/graphics/FontUtils.cpp \
-    android/graphics/CreateJavaOutputStreamAdaptor.cpp \
-    android/graphics/GIFMovie.cpp \
-    android/graphics/GraphicBuffer.cpp \
-    android/graphics/Graphics.cpp \
-    android/graphics/HarfBuzzNGFaceSkia.cpp \
-    android/graphics/Interpolator.cpp \
-    android/graphics/MaskFilter.cpp \
-    android/graphics/Matrix.cpp \
-    android/graphics/Movie.cpp \
-    android/graphics/MovieImpl.cpp \
-    android/graphics/NinePatch.cpp \
-    android/graphics/NinePatchPeeker.cpp \
-    android/graphics/Paint.cpp \
-    android/graphics/Path.cpp \
-    android/graphics/PathMeasure.cpp \
-    android/graphics/PathEffect.cpp \
-    android/graphics/Picture.cpp \
-    android/graphics/BitmapRegionDecoder.cpp \
-    android/graphics/Region.cpp \
-    android/graphics/Shader.cpp \
-    android/graphics/SurfaceTexture.cpp \
-    android/graphics/Typeface.cpp \
-    android/graphics/Utils.cpp \
-    android/graphics/YuvToJpegEncoder.cpp \
-    android/graphics/pdf/PdfDocument.cpp \
-    android/graphics/pdf/PdfEditor.cpp \
-    android/graphics/pdf/PdfRenderer.cpp \
-    android/graphics/pdf/PdfUtils.cpp \
-    android_media_AudioRecord.cpp \
-    android_media_AudioSystem.cpp \
-    android_media_AudioTrack.cpp \
-    android_media_DeviceCallback.cpp \
-    android_media_JetPlayer.cpp \
-    android_media_RemoteDisplay.cpp \
-    android_media_ToneGenerator.cpp \
-    android_hardware_Camera.cpp \
-    android_hardware_camera2_CameraMetadata.cpp \
-    android_hardware_camera2_legacy_LegacyCameraDevice.cpp \
-    android_hardware_camera2_legacy_PerfMeasurement.cpp \
-    android_hardware_camera2_DngCreator.cpp \
-    android_hardware_HardwareBuffer.cpp \
-    android_hardware_Radio.cpp \
-    android_hardware_SensorManager.cpp \
-    android_hardware_SerialPort.cpp \
-    android_hardware_SoundTrigger.cpp \
-    android_hardware_UsbDevice.cpp \
-    android_hardware_UsbDeviceConnection.cpp \
-    android_hardware_UsbRequest.cpp \
-    android_hardware_location_ActivityRecognitionHardware.cpp \
-    android_util_FileObserver.cpp \
-    android/opengl/poly_clip.cpp.arm \
-    android/opengl/util.cpp \
-    android_server_NetworkManagementSocketTagger.cpp \
-    android_server_Watchdog.cpp \
-    android_ddm_DdmHandleNativeHeap.cpp \
-    android_backup_BackupDataInput.cpp \
-    android_backup_BackupDataOutput.cpp \
-    android_backup_FileBackupHelperBase.cpp \
-    android_backup_BackupHelperDispatcher.cpp \
-    android_app_backup_FullBackup.cpp \
-    android_content_res_ObbScanner.cpp \
-    android_content_res_Configuration.cpp \
-    android_animation_PropertyValuesHolder.cpp \
-    com_android_internal_net_NetworkStatsFactory.cpp \
-    com_android_internal_os_FuseAppLoop.cpp \
-    com_android_internal_os_PathClassLoaderFactory.cpp \
-    com_android_internal_os_Zygote.cpp \
-    com_android_internal_util_VirtualRefBasePtr.cpp \
-    com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
-    hwbinder/EphemeralStorage.cpp \
-    fd_utils.cpp \
-
-LOCAL_C_INCLUDES += \
-    $(LOCAL_PATH)/include \
-    $(JNI_H_INCLUDE) \
-    $(LOCAL_PATH)/android/graphics \
-    $(LOCAL_PATH)/../../libs/hwui \
-    $(LOCAL_PATH)/../../../native/vulkan/include \
-    $(call include-path-for, bluedroid) \
-    $(call include-path-for, libhardware)/hardware \
-    $(call include-path-for, libhardware_legacy)/hardware_legacy \
-    $(TOP)/frameworks/base/media/jni \
-    $(TOP)/frameworks/rs/cpp \
-    $(TOP)/frameworks/rs \
-    $(TOP)/system/core/base/include \
-    $(TOP)/system/core/include \
-    $(TOP)/system/core/libappfuse/include \
-    $(TOP)/system/media/camera/include \
-    $(TOP)/system/media/private/camera/include \
-    $(TOP)/system/netd/include \
-    external/giflib \
-    external/pdfium/public \
-    external/skia/include/private \
-    external/skia/src/codec \
-    external/skia/src/core \
-    external/skia/src/effects \
-    external/skia/src/image \
-    external/skia/src/images \
-    external/sqlite/dist \
-    external/sqlite/android \
-    external/tremor/Tremor \
-    external/harfbuzz_ng/src \
-    libcore/include \
-    $(call include-path-for, audio-utils) \
-    frameworks/minikin/include \
-    external/freetype/include
-# TODO: clean up Minikin so it doesn't need the freetype include
-
-LOCAL_STATIC_LIBRARIES := \
-    libgif \
-    libseccomp_policy \
-    libselinux \
-    libcrypto \
-    libgrallocusage \
-
-LOCAL_SHARED_LIBRARIES := \
-    libmemtrack \
-    libandroidfw \
-    libappfuse \
-    libbase \
-    libnativehelper \
-    liblog \
-    libcutils \
-    libdebuggerd_client \
-    libutils \
-    libbinder \
-    libui \
-    libgui \
-    libsensor \
-    libinput \
-    libcamera_client \
-    libcamera_metadata \
-    libskia \
-    libsqlite \
-    libEGL \
-    libGLESv1_CM \
-    libGLESv2 \
-    libvulkan \
-    libziparchive \
-    libETC1 \
-    libhardware \
-    libhardware_legacy \
-    libselinux \
-    libicuuc \
-    libmedia \
-    libaudioclient \
-    libjpeg \
-    libusbhost \
-    libharfbuzz_ng \
-    libz \
-    libpdfium \
-    libimg_utils \
-    libnetd_client \
-    libradio \
-    libsoundtrigger \
-    libminikin \
-    libprocessgroup \
-    libnativebridge \
-    libradio_metadata \
-    libnativeloader \
-    libmemunreachable \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    libvintf \
-    libnativewindow \
-
-LOCAL_SHARED_LIBRARIES += \
-    libhwui \
-    libdl \
-
-# our headers include libnativewindow's public headers
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
-    libnativewindow \
-
-# we need to access the private Bionic header
-# <bionic_tls.h> in com_google_android_gles_jni_GLImpl.cpp
-LOCAL_C_INCLUDES += bionic/libc/private
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-# AndroidRuntime.h depends on nativehelper/jni.h
-LOCAL_EXPORT_C_INCLUDE_DIRS += libnativehelper/include
-
-LOCAL_MODULE:= libandroid_runtime
-
-# -Wno-unknown-pragmas: necessary for Clang as the GL bindings need to turn
-#                       off a GCC warning that Clang doesn't know.
-LOCAL_CFLAGS += -Wall -Werror -Wno-error=deprecated-declarations -Wunused -Wunreachable-code \
-        -Wno-unknown-pragmas
-
-# -Wno-c++11-extensions: Clang warns about Skia using the C++11 override keyword, but this project
-#                        is not being compiled with that level. Remove once this has changed.
-LOCAL_CLANG_CFLAGS += -Wno-c++11-extensions
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index fc90fb3..9ad57b1 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -41,9 +41,6 @@
 
 namespace android {
 
-// Must be same with Java constant in Typeface.Builder. See Typeface.java
-constexpr jint RESOLVE_BY_FONT_TABLE = -1;
-
 struct NativeFamilyBuilder {
     NativeFamilyBuilder(uint32_t langId, int variant)
         : langId(langId), variant(variant), allowUnsupportedFont(false) {}
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 86c97a1..eb2ca5d 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -30,14 +30,14 @@
 
 static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
     Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
-    Typeface* face = Typeface::createFromTypeface(family, (SkTypeface::Style)style);
+    Typeface* face = Typeface::createRelative(family, (SkTypeface::Style)style);
     // TODO: the following logic shouldn't be necessary, the above should always succeed.
     // Try to find the closest matching font, using the standard heuristic
     if (NULL == face) {
-        face = Typeface::createFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
+        face = Typeface::createRelative(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
     }
     for (int i = 0; NULL == face && i < 4; i++) {
-        face = Typeface::createFromTypeface(family, (SkTypeface::Style)i);
+        face = Typeface::createRelative(family, (SkTypeface::Style)i);
     }
     return reinterpret_cast<jlong>(face);
 }
@@ -45,8 +45,7 @@
 static jlong Typeface_createFromTypefaceWithExactStyle(JNIEnv* env, jobject, jlong nativeInstance,
         jint weight, jboolean italic) {
     Typeface* baseTypeface = reinterpret_cast<Typeface*>(nativeInstance);
-    return reinterpret_cast<jlong>(
-            Typeface::createFromTypefaceWithStyle(baseTypeface, weight, italic));
+    return reinterpret_cast<jlong>(Typeface::createAbsolute(baseTypeface, weight, italic));
 }
 
 static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlong familyHandle,
@@ -68,7 +67,7 @@
 
 static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle, jint weight) {
     Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
-    Typeface* face = Typeface::createWeightAlias(family, weight);
+    Typeface* face = Typeface::createWithDifferentBaseWeight(family, weight);
     return reinterpret_cast<jlong>(face);
 }
 
@@ -82,9 +81,9 @@
     return face->fSkiaStyle;
 }
 
-static jint Typeface_getBaseWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
+static jint Typeface_getWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
     Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
-    return face->fBaseWeight;
+    return face->fStyle.getWeight() * 100;
 }
 
 static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray,
@@ -134,7 +133,7 @@
     { "nativeCreateWeightAlias",  "(JI)J", (void*)Typeface_createWeightAlias },
     { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
     { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
-    { "nativeGetBaseWeight",      "(J)I",  (void*)Typeface_getBaseWeight },
+    { "nativeGetWeight",      "(J)I",  (void*)Typeface_getWeight },
     { "nativeCreateFromArray",    "([JII)J",
                                            (void*)Typeface_createFromArray },
     { "nativeSetDefault",         "(J)V",   (void*)Typeface_setDefault },
diff --git a/core/jni/android_hardware_location_ActivityRecognitionHardware.cpp b/core/jni/android_hardware_location_ActivityRecognitionHardware.cpp
index b23757e..637234f 100644
--- a/core/jni/android_hardware_location_ActivityRecognitionHardware.cpp
+++ b/core/jni/android_hardware_location_ActivityRecognitionHardware.cpp
@@ -22,7 +22,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/Log.h>
 
-// #include "activity_recognition.h"
+// #include <hardware/activity_recognition.h>
 // The activity recognition HAL is being deprecated. This means -
 //    i) Android framework code shall not depend on activity recognition
 //       being provided through the activity_recognition.h interface.
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 2cfaeeb..3e9ffce 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -28,7 +28,6 @@
 #include <utils/Log.h>
 #include <media/AudioSystem.h>
 #include <media/AudioTrack.h>
-#include <audio_utils/primitives.h>
 
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 033f2df..fa9379e 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -23,23 +23,34 @@
 
 #include <JNIHelp.h>
 #include <vintf/VintfObject.h>
+#include <vintf/parse_string.h>
 #include <vintf/parse_xml.h>
 
 #include "core_jni_helpers.h"
 
 static jclass gString;
+static jclass gHashMapClazz;
+static jmethodID gHashMapInit;
+static jmethodID gHashMapPut;
 
 namespace android {
 
+using vintf::HalManifest;
+using vintf::SchemaType;
 using vintf::VintfObject;
+using vintf::XmlConverter;
+using vintf::Vndk;
 using vintf::gHalManifestConverter;
 using vintf::gCompatibilityMatrixConverter;
-using vintf::XmlConverter;
+using vintf::to_string;
 
-static inline jobjectArray toJavaStringArray(JNIEnv* env, const std::vector<std::string>& v) {
+template<typename V>
+static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
+    size_t i;
+    typename V::const_iterator it;
     jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */);
-    for (size_t i = 0; i < v.size(); ++i) {
-        env->SetObjectArrayElement(ret, i, env->NewStringUTF(v[i].c_str()));
+    for (i = 0, it = v.begin(); it != v.end(); ++i, ++it) {
+        env->SetObjectArrayElement(ret, i, env->NewStringUTF(it->c_str()));
     }
     return ret;
 }
@@ -55,7 +66,18 @@
     }
 }
 
-static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass clazz)
+static void tryAddHalNamesAndVersions(const HalManifest *manifest,
+        const std::string& description,
+        std::set<std::string> *output) {
+    if (manifest == nullptr) {
+        LOG(WARNING) << __FUNCTION__ << "Cannot get " << description;
+    } else {
+        auto names = manifest->getHalNamesAndVersions();
+        output->insert(names.begin(), names.end());
+    }
+}
+
+static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass)
 {
     std::vector<std::string> cStrings;
 
@@ -71,7 +93,7 @@
     return toJavaStringArray(env, cStrings);
 }
 
-static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) {
+static jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) {
     size_t count = env->GetArrayLength(packageInfo);
     std::vector<std::string> cPackageInfo{count};
     for (size_t i = 0; i < count; ++i) {
@@ -84,20 +106,60 @@
     return status;
 }
 
+static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
+    std::set<std::string> halNames;
+    tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
+            "device manifest", &halNames);
+    tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
+            "framework manifest", &halNames);
+    return toJavaStringArray(env, halNames);
+}
+
+static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
+    const HalManifest *manifest = VintfObject::GetDeviceHalManifest();
+    if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
+        LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
+        return nullptr;
+    }
+    std::string cString = to_string(manifest->sepolicyVersion());
+    return env->NewStringUTF(cString.c_str());
+}
+
+static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
+    const HalManifest *manifest = VintfObject::GetFrameworkHalManifest();
+    if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
+        LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
+        return nullptr;
+    }
+    jobject jMap = env->NewObject(gHashMapClazz, gHashMapInit);
+    for (const Vndk &vndk : manifest->vndks()) {
+        std::string key = to_string(vndk.versionRange());
+        env->CallObjectMethod(jMap, gHashMapPut,
+                env->NewStringUTF(key.c_str()), toJavaStringArray(env, vndk.libraries()));
+    }
+    return jMap;
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gVintfObjectMethods[] = {
     {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
     {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
+    {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions},
+    {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion},
+    {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots},
 };
 
-
 const char* const kVintfObjectPathName = "android/os/VintfObject";
 
 int register_android_os_VintfObject(JNIEnv* env)
 {
 
     gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
+    gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
+    gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
+    gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
+            "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
 
     return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
             NELEM(gVintfObjectMethods));
diff --git a/core/res/res/drawable/sym_def_app_icon.xml b/core/res/res/drawable/sym_def_app_icon.xml
index 0fdb0dd..9c02402 100644
--- a/core/res/res/drawable/sym_def_app_icon.xml
+++ b/core/res/res/drawable/sym_def_app_icon.xml
@@ -2,10 +2,7 @@
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
     <background android:drawable="@android:color/white" />
     <foreground>
-        <inset android:insetLeft="27.7%"
-            android:insetTop="27.7%"
-            android:insetRight="27.7%"
-            android:insetBottom="27.7%">
+        <inset android:inset="27.7%">
             <bitmap android:src="@mipmap/sym_def_app_icon"/>
         </inset>
     </foreground>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 3477a7e..f0f4f44 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -82,7 +82,7 @@
     <string name="ThreeWCMmi" msgid="9051047170321190368">"Drierigtingbel"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"Verwerping van ongewenste, irriterende oproepe"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Oproepnommer-lewering"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"Moenie steur nie"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Moenie Steur Nie"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Beller-ID se verstek is beperk. Volgende oproep: beperk"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Beller-ID se verstek is beperk. Volgende oproep: nie beperk nie"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Beller-ID se verstek is nie beperk nie. Volgende oproep: beperk"</string>
@@ -553,8 +553,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Dit laat die houer toe om aan die top-koppelvlak van \'n diensverskaffer-boodskapdiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"verbind aan diensverskafferdienste"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Laat die houer toe om aan diensverskafferdienste te verbind. Behoort nooit vir normale programme nodig te wees nie."</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"verkry toegang tot Moenie steur nie"</string>
-    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Laat die program toe om Moenie steur nie-opstelling te lees en skryf."</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"verkry toegang tot Moenie Steur Nie"</string>
+    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Laat die program toe om Moenie Steur Nie-opstelling te lees en skryf."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="2502021457917874968">"Beheer die lengte en die karakters wat in skermslotwagwoorde en -PIN\'e toegelaat word."</string>
     <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor pogings om skerm te ontsluit"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksaksies"</string>
     <string name="email" msgid="4560673117055050403">"E-pos"</string>
     <string name="dial" msgid="4204975095406423102">"Foon"</string>
-    <string name="map" msgid="5441053548030107189">"Kaart"</string>
-    <string name="browse" msgid="6079864138582486027">"Blaai"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Bergingspasie word min"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sommige stelselfunksies werk moontlik nie"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nie genoeg berging vir die stelsel nie. Maak seker jy het 250 MB spasie beskikbaar en herbegin."</string>
@@ -1653,11 +1655,11 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (volgende wekker)"</string>
-    <string name="zen_mode_forever" msgid="1916263162129197274">"Totdat jy Moenie steur nie afskakel"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Totdat jy Moenie steur nie afskakel"</string>
+    <string name="zen_mode_forever" msgid="1916263162129197274">"Totdat jy Moenie Steur Nie afskakel"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Totdat jy Moenie Steur Nie afskakel"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Vou in"</string>
-    <string name="zen_mode_feature_name" msgid="5254089399895895004">"Moenie steur nie"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"Moenie Steur Nie"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Staantyd"</string>
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Weeksaand"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Naweek"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 6d2aa7a..62d1924 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
     <string name="email" msgid="4560673117055050403">"ኢሜይል"</string>
     <string name="dial" msgid="4204975095406423102">"ስልክ"</string>
-    <string name="map" msgid="5441053548030107189">"ካርታ"</string>
-    <string name="browse" msgid="6079864138582486027">"አስስ"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"የማከማቻ ቦታ እያለቀ ነው"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"አንዳንድ የስርዓት ተግባራት ላይሰሩ ይችላሉ"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ለስርዓቱ የሚሆን በቂ ቦታ የለም። 250 ሜባ ነጻ ቦታ እንዳለዎት ያረጋግጡና ዳግም ያስጀምሩ።"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"ዩኤስቢ ለMIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ለUSB ተቀጥላ ተያይዟል"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"የኦዲዮ መለዋወጫ አይደገፍም"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ተጨማሪ መረጃ ለማግኘት መታ ያድርጉ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"የዩኤስቢ ማረሚያን ለማሰናከል መታ ያድርጉ።"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a080138..ee8bb38 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1064,8 +1064,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
     <string name="email" msgid="4560673117055050403">"بريد إلكتروني"</string>
     <string name="dial" msgid="4204975095406423102">"الهاتف"</string>
-    <string name="map" msgid="5441053548030107189">"خريطة"</string>
-    <string name="browse" msgid="6079864138582486027">"تصفح"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"مساحة التخزين منخفضة"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"قد لا تعمل بعض وظائف النظام"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ليست هناك سعة تخزينية كافية للنظام. تأكد من أنه لديك مساحة خالية تبلغ ٢٥٠ ميغابايت وأعد التشغيل."</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 72d0bdc..d113852 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Mətn əməliyyatları"</string>
     <string name="email" msgid="4560673117055050403">"E-poçt"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Xəritə"</string>
-    <string name="browse" msgid="6079864138582486027">"Axtarış"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Yaddaş yeri bitir"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bəzi sistem funksiyaları işləməyə bilər"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistem üçün yetərincə yaddaş ehtiyatı yoxdur. 250 MB yaddaş ehtiyatının olmasına əmin olun və yenidən başladın."</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 6667a414..2491383 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -269,9 +269,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije pokrenute u pozadini"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> radi u pozadini"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) su pokrenute u pozadini"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste pregledali detalje o bateriji i potrošnji podataka"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje u vezi sa tekstom"</string>
     <string name="email" msgid="4560673117055050403">"Pošalji imejl"</string>
     <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pregledaj"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memorijski prostor je na izmaku"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda ne funkcionišu"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno memorijskog prostora za sistem. Uverite se da imate 250 MB slobodnog prostora i ponovo pokrenite."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c564168..2652cc2 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -274,7 +274,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Праграмы, якія працуюць у фонавым рэжыме"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе ў фонавым рэжыме"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Праграмы (<xliff:g id="NUMBER">%1$d</xliff:g>) працуюць у фонавым рэжыме"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Дакраніцеся, каб атрымаць падрабязныя звесткі пра выкарыстанне трафіка і акумулятара"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string>
@@ -1023,9 +1023,11 @@
     <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
     <string name="email" msgid="4560673117055050403">"Электронная пошта"</string>
-    <string name="dial" msgid="4204975095406423102">"Патэлефанаваць"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Праглядзець"</string>
+    <string name="dial" msgid="4204975095406423102">"Тэлефон"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Не хапае сховішча для сістэмы. Пераканайцеся, што ў вас ёсць 250 МБ свабоднага месца, і перазапусціце."</string>
@@ -1066,7 +1068,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Выберыце дзеянне"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Выберыце прыкладанне для USB-прылады"</string>
     <string name="noApplications" msgid="2991814273936504689">"Няма прыкладанняў, якія могуць выконваць гэты працэс."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Праграма <xliff:g id="APPLICATION">%1$s</xliff:g> спынілася"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g>: збой у рабоце"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> спыніўся"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> шматразова спыняе працу"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> шматразова спыняе працу"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 8c78183..faa8ca6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрационен режим за магазини"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB връзка"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работещи на заден план"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> работи на заден план"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява на заден план"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения работят на заден план"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Докоснете за подробности относно използването на батерията и преноса на данни"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
     <string name="email" msgid="4560673117055050403">"Имейл"</string>
     <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Сърфиране"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Мястото в хранилището е на изчерпване"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Възможно е някои функции на системата да не работят"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"За системата няма достатъчно място в хранилището. Уверете се, че имате свободни 250 МБ, и рестартирайте."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Установена е връзка с аксесоар за USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Докоснете за още опции."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоаксесоарът не се поддържа"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Докоснете за още информация"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Докоснете, за да деактивирате отстраняването на грешки през USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 4eaa927..f2b5c04 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"পাঠ্য ক্রিয়াগুলি"</string>
     <string name="email" msgid="4560673117055050403">"ইমেল"</string>
     <string name="dial" msgid="4204975095406423102">"ফোন করুন"</string>
-    <string name="map" msgid="5441053548030107189">"মানচিত্র"</string>
-    <string name="browse" msgid="6079864138582486027">"ব্রাউজ করুন"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"সঞ্চয়স্থান পূর্ণ হতে চলেছে"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"কিছু কিছু সিস্টেম ক্রিয়াকলাপ কাজ নাও করতে পারে"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"সিস্টেমের জন্য যথেষ্ট সঞ্চয়স্থান নেই৷ আপনার কাছে ২৫০MB ফাঁকা স্থান রয়েছে কিনা সে বিষয়ে নিশ্চিত হওয়ার পর আবার চালু করুন৷"</string>
@@ -1119,7 +1121,7 @@
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ওয়াই-ফাই এর সাথে সংযোগ করা যায়নি"</string>
     <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" একটি দুর্বল ইন্টারনেট সংযোগ রয়েছে৷"</string>
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"সংযোগের অনুমতি দেবেন?"</string>
-    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"অ্যাপ্লিকেশান %1$s Wifi নেটওয়ার্ক %2$s এর সাথে সংযোগ করতে চায়"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"অ্যাপ্লিকেশান %1$s ওয়াই ফাই নেটওয়ার্ক %2$s এর সাথে সংযোগ করতে চায়"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"একটি অ্যাপ্লিকেশান"</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"ওয়াই-ফাই ডাইরেক্ট"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ওয়াই-ফাই ডাইরেক্ট আরম্ভ করুন৷ এটি ওয়াই-ফাই client/hotspot কে বন্ধ করবে৷"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI এর জন্য USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"একটি USB যন্ত্রাংশতে সংযুক্ত হয়েছে"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"আরো বিকল্পের জন্য আলতো চাপুন৷"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"অডিও অ্যাক্সেসরি সমর্থিত নয়"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ডিবাগিং অক্ষম করতে আলতো চাপুন৷"</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index e811f71..ff41718 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -211,7 +211,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Priprema za ažuriranje..."</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Obrađuje se paket ažuriranja..."</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Ponovno se pokreće..."</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na tvorničke postavke"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na fabričke postavke"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Ponovno se pokreće..."</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Gašenje u toku…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tablet će se isključiti."</string>
@@ -228,7 +228,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Opcije telefona"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Zaključavanje ekrana"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Isključi telefon"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Hitni slučaj"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Hitno"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvještaj o greškama"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kreirajte izvještaj o greškama"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao poruka e-pošte. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
@@ -269,9 +269,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Promotivna demonstracija u maloprodaji"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije koje rade u pozadini"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> radi u pozadini"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta u pozadini"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Broj aplikacija koje rade u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o bateriji i prijenosu podataka"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
@@ -409,7 +409,7 @@
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Omogućava aplikaciji slanje naredbi na SIM. Ovo je vrlo opasno."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"snimanje slika i videozapisa"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Ova aplikacija može slikati fotografije i snimati videozapise koristeći kameru bilo kada."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibriranja"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibracije"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"izravno zvanje telefonskih brojeva"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
@@ -718,7 +718,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pritisnite dugme Meni kako biste otključali uređaj ili obavili hitni poziv."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pritisnite dugme Meni za otključavanje uređaja."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Nacrtajte uzorak za otključavanje"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitni slučaj"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitno"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Povratak na poziv"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ispravno!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Pokušajte ponovo"</string>
@@ -847,7 +847,7 @@
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji dodavanje poruka u vašu ulaznu govornu poštu."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih dozvola preglednika"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih dozvola pretraživača. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web stranicama."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih odobrenja preglednika. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web lokcacijama."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu lozinku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
     <string name="dial" msgid="4204975095406423102">"Pozovi"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Pretraži"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string>
@@ -1216,7 +1218,7 @@
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string>
     <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
-    <string name="hardware" msgid="194658061510127999">"Prikaži virtuelnu tastaturu"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaz virtuelne tastature"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguriraj fizičku tastaturu"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite za odabir jezika i rasporeda"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1395,7 +1397,7 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Uredi"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"Upozorenje o prijenosu podataka"</string>
-    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz upotrebe i postavki."</string>
+    <string name="data_usage_warning_body" msgid="6660692274311972007">"Dodirnite za prikaz potrošnje i postavki."</string>
     <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dostignut limit za 2G-3G podatke"</string>
     <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dostignut limit za 4G podatke"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"Dostignut limit za mob. podatke"</string>
@@ -1441,7 +1443,7 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bežični prikaz"</string>
-    <string name="media_route_button_content_description" msgid="591703006349356016">"Prebacuj"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Emitiranje"</string>
     <string name="media_route_chooser_title" msgid="1751618554539087622">"Poveži na uređaj"</string>
     <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Emitiranje ekrana na uređaj"</string>
     <string name="media_route_chooser_searching" msgid="4776236202610828706">"Traženje uređajā…"</string>
@@ -1643,7 +1645,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Instalirao je vaš administrator"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao je vaš administrator"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao je vaš administrator"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produžilo trajanje baterije, opcija za štednju baterije minimizira rad uređaja i ograničava vibriranje, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu biti ažurirane dok ih ne otvorite.\n\nŠtednja baterije se automatski isključuje prilikom punjenja uređaja."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produžilo trajanje baterije, opcija za uštedu baterije minimizira rad uređaja i ograničava vibraciju, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu se ažurirati dok ih ne otvorite.\n\nUšteda baterije se automatski isključuje prilikom punjenja uređaja."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio prijenos podataka, usluga Ušteda podataka sprečava da neke aplikacije šalju ili primaju podatke u pozadini. Aplikacija koju trenutno koristite može pristupiti podacima, ali se to može desiti rjeđe. To može značiti, naprimjer, da se slike ne prikazuju sve dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a3e9fc9..a15f902 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacions que s\'estan executant en segon pla"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant en segon pla"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions s\'estan executant en segon pla"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca per obtenir informació sobre l\'ús de dades i la bateria"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string>
     <string name="email" msgid="4560673117055050403">"Correu electrònic"</string>
     <string name="dial" msgid="4204975095406423102">"Truca"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Navega"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"L\'espai d\'emmagatzematge s\'està esgotant"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"És possible que algunes funcions del sistema no funcionin"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hi ha prou espai d\'emmagatzematge per al sistema. Comprova que tinguis 250 MB d\'espai lliure i reinicia."</string>
@@ -1026,7 +1028,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Tria una acció"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Tria una aplicació per al dispositiu USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"No hi ha cap aplicació que pugui dur a terme aquesta acció."</string>
-    <string name="aerr_application" msgid="250320989337856518">"S\'ha aturat l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="aerr_application" msgid="250320989337856518">"S\'ha aturat <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> s\'ha aturat"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"L\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> s\'atura contínuament"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> s\'atura contínuament"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per a MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connectat a un accessori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca per veure més opcions."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"L\'accessori d\'àudio no és compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca per obtenir més informació"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca per desactivar la depuració USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració USB"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e02eaec..20a1a83 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -272,7 +272,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodejní ukázka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Připojení USB"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikace běžící na pozadí"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> běží na pozadí"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> běží na pozadí"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) běží na pozadí"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
     <string name="email" msgid="4560673117055050403">"Poslat e-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Procházet"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Pro systém není dostatek místa v úložišti. Uvolněte alespoň 250 MB místa a restartujte zařízení."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b1df60b..47ba065 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Opkald"</string>
-    <string name="map" msgid="5441053548030107189">"Kort"</string>
-    <string name="browse" msgid="6079864138582486027">"Gennemse"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der er snart ikke mere lagerplads"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nogle systemfunktioner virker måske ikke"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der er ikke nok ledig lagerplads til systemet. Sørg for, at du har 250 MB ledig plads, og genstart."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB til MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryk for at se flere muligheder."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret understøttes ikke"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryk for at få flere oplysninger"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryk for at deaktivere fejlretning via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d7810a2..eb31a1d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps, die im Hintergrund ausgeführt werden"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird im Hintergrund ausgeführt"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps werden im Hintergrund ausgeführt"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Für weitere Informationen zur Akku- und Datennutzung tippen"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Für Details zur Akku- und Datennutzung tippen"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
     <string name="email" msgid="4560673117055050403">"E-Mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Karte"</string>
-    <string name="browse" msgid="6079864138582486027">"Stöbern"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Der Speicherplatz reicht nicht für das System aus. Stelle sicher, dass 250 MB freier Speicherplatz vorhanden sind, und starte das Gerät dann neu."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB für MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Mit USB-Zubehör verbunden"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Für weitere Optionen tippen."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audiozubehör wird nicht unterstützt"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tippen, um weitere Informationen zu erhalten"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging aktiviert"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Zum Deaktivieren von USB-Debugging tippen."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cda02d2..0350651 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
     <string name="email" msgid="4560673117055050403">"Ηλεκτρονικό ταχυδρομείο"</string>
     <string name="dial" msgid="4204975095406423102">"Τηλέφωνο"</string>
-    <string name="map" msgid="5441053548030107189">"Χάρτης"</string>
-    <string name="browse" msgid="6079864138582486027">"Αναζήτηση"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ο αποθηκευτικός χώρος εξαντλείται"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ορισμένες λειτουργίες συστήματος ενδέχεται να μην λειτουργούν"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Δεν υπάρχει αρκετός αποθηκευτικός χώρος για το σύστημα. Βεβαιωθείτε ότι διαθέτετε 250 MB ελεύθερου χώρου και κάντε επανεκκίνηση."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index d1d474b..b8306d6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="5441053548030107189">"Map"</string>
-    <string name="browse" msgid="6079864138582486027">"Browse"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d1d474b..b8306d6 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="5441053548030107189">"Map"</string>
-    <string name="browse" msgid="6079864138582486027">"Browse"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index d1d474b..b8306d6 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Phone"</string>
-    <string name="map" msgid="5441053548030107189">"Map"</string>
-    <string name="browse" msgid="6079864138582486027">"Browse"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Not enough storage for the system. Make sure that you have 250 MB of free space and restart."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index d95cdb6..cf7be8b 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
     <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Explorar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio de almacenamiento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no estén disponibles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hay espacio suficiente para el sistema. Asegúrate de que haya 250 MB libres y reinicia el dispositivo."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a986c21..aab1f12 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicaciones que se están ejecutando en segundo plano"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en segundo plano"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones se están ejecutando en segundo plano"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para ver información detallada sobre el uso de datos y la batería"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
     <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Explorar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no funcionen."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"No hay espacio suficiente para el sistema. Comprueba que haya 250 MB libres y reinicia el dispositivo."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c426454..fd69de34 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
     <string name="email" msgid="4560673117055050403">"E-post"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Kaart"</string>
-    <string name="browse" msgid="6079864138582486027">"Sirvimine"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Süsteemis pole piisavalt talletusruumi. Veenduge, et seadmes oleks 250 MB vaba ruumi, ja käivitage seade uuesti."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI jaoks"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Puudutage lisavalikute nägemiseks."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Helitarvikut ei toetata"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Puudutage lisateabe saamiseks"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Puudutage USB-silumise keelamiseks."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index c4585de..ef58549 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> exekutatzen ari da atzeko planoan"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> exekutatzen ari dira atzeko planoan"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Sakatu bateriaren eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistema"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Testu-ekintzak"</string>
     <string name="email" msgid="4560673117055050403">"Posta"</string>
     <string name="dial" msgid="4204975095406423102">"Telefonoa"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Arakatu"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Memoria betetzen ari da"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sistemaren funtzio batzuek ez dute agian funtzionatuko"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sisteman ez dago behar adina memoria. Ziurtatu gutxienez 250 MB erabilgarri dituzula eta, ondoren, berrabiarazi gailua."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b12951a..ca70e9a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"عملکردهای متنی"</string>
     <string name="email" msgid="4560673117055050403">"رایانامه"</string>
     <string name="dial" msgid="4204975095406423102">"تلفن"</string>
-    <string name="map" msgid="5441053548030107189">"نقشه"</string>
-    <string name="browse" msgid="6079864138582486027">"مرور"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"حافظه درحال پر شدن است"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"فضای ذخیره‌سازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راه‌اندازی مجدد کنید."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB برای MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏به یک وسیله جانبی USB وصل شده است"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"برای گزینه‌های بیشتر ضربه بزنید."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"وسیله جانبی صوتی پشتیبانی نمی‌شود"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"برای اطلاعات بیشتر ضربه بزنید"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏برای غیرفعال کردن اشکال‌زدایی USB ضربه بزنید."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4d1b075..1408456 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -266,7 +266,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Esittelytila"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-yhteys"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Sovelluksia käynnissä taustalla"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä taustalla."</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä taustalla"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta on käynnissä taustalla."</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Katso lisätietoja akun ja datan käytöstä napauttamalla."</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoiminnot"</string>
     <string name="email" msgid="4560673117055050403">"Sähköposti"</string>
     <string name="dial" msgid="4204975095406423102">"Puhelin"</string>
-    <string name="map" msgid="5441053548030107189">"Kartta"</string>
-    <string name="browse" msgid="6079864138582486027">"Selaa"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Tallennustila loppumassa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kaikki järjestelmätoiminnot eivät välttämättä toimi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tallennustila ei riitä. Varmista, että vapaata tilaa on 250 Mt, ja käynnistä uudelleen."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index b067fb9..3b8716c 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="8340973892742019101">"B"</string>
+    <string name="byteShort" msgid="8340973892742019101">"o"</string>
     <string name="kilobyteShort" msgid="7542884022844556968">"ko"</string>
     <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string>
     <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Applications qui fonctionnent en arrière-plan"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> fonctionne en arrière-plan"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> applications fonctionnent en arrière-plan"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Touchez ici pour afficher des détails sur l\'usage de la pile et des données"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="email" msgid="4560673117055050403">"Courriel"</string>
     <string name="dial" msgid="4204975095406423102">"Téléphone"</string>
-    <string name="map" msgid="5441053548030107189">"Carte"</string>
-    <string name="browse" msgid="6079864138582486027">"Parcourir"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB pour MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Touchez pour afficher plus d\'options."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non pris en charge"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Touchez l\'écran pour obtenir plus d\'information"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Touchez pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ba33460..689755d 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Téléphone"</string>
-    <string name="map" msgid="5441053548030107189">"Carte"</string>
-    <string name="browse" msgid="6079864138582486027">"Parcourir"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB en mode MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Appuyez ici pour plus d\'options."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Accessoire audio non compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Appuyer pour afficher plus d\'informations"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Appuyez ici pour désactiver le débogage USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 0a5ba2c..ebb908e 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -28,9 +28,9 @@
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
     <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> días"</string>
-    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> hrs"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
     <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> día <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
-    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> hrs"</string>
+    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string>
     <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
     <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacións que se executan en segundo plano"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Estase executando en segundo plano a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Estanse executando en segundo plano <xliff:g id="NUMBER">%1$d</xliff:g> aplicacións"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para obter información sobre a batería e o uso de datos"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para obter información sobre o uso de datos e a batería"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accións de texto"</string>
     <string name="email" msgid="4560673117055050403">"Correo electrónico"</string>
     <string name="dial" msgid="4204975095406423102">"Teléfono"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Examinar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Estase esgotando o espazo de almacenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"É posible que algunhas funcións do sistema non funcionen"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Non hai almacenamento suficiente para o sistema. Asegúrate de ter un espazo libre de 250 MB e reinicia o dispositivo."</string>
@@ -1026,8 +1028,8 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Escoller unha acción"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Selecciona unha aplicación para o dispositivo USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Ningunha aplicación pode realizar esta acción."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Detívose <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
-    <string name="aerr_process" msgid="6201597323218674729">"Detívose <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> deixou de funcionar"</string>
+    <string name="aerr_process" msgid="6201597323218674729">"O proceso <xliff:g id="PROCESS">%1$s</xliff:g>  deixou de funcionar"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> segue deténdose"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> segue deténdose"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Abrir aplicación de novo"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Toca para ver máis opcións."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"O accesorio de audio non é compatible"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Toca para obter máis información"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Toca para desactivar a depuración de erros de USB."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1193,7 +1193,7 @@
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ANULAR"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
-    <string name="show_ime" msgid="2506087537466597099">"Manteno na pantalla mentres o teclado físico estea activo"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Móstrase na pantalla mentres o teclado físico estea activo"</string>
     <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura o teclado físico"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar o idioma e o deseño"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 54c493d1..2d57cc3 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ટેક્સ્ટ ક્રિયાઓ"</string>
     <string name="email" msgid="4560673117055050403">"ઇમેઇલ"</string>
     <string name="dial" msgid="4204975095406423102">"ફોન"</string>
-    <string name="map" msgid="5441053548030107189">"નકશો"</string>
-    <string name="browse" msgid="6079864138582486027">"બ્રાઉઝ કરો"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"સ્ટોરેજ સ્થાન સમાપ્ત થયું"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"કેટલાક સિસ્ટમ કાર્યો કામ કરી શકશે નહીં"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"સિસ્ટમ માટે પર્યાપ્ત સ્ટોરેજ નથી. ખાતરી કરો કે તમારી પાસે 250MB ખાલી સ્થાન છે અને ફરીથી પ્રારંભ કરો."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI માટે USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ઍક્સેસરીથી કનેક્ટ થયાં"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ઑડિયો ઍક્સેસરી સમર્થિત નથી"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"વધુ માહિતી માટે ટૅપ કરો"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ડીબગિંગ અક્ષમ કરવા માટે ટૅપ કરો."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 74a7a04..a31546b 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -265,10 +265,10 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुदरा डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्शन"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैकग्राउंड में चल रहा है"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा उपयोग के विवरण पाने के लिए टैप करें"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा उपयोग के विवरण देखने के लिए टैप करें"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android सिस्‍टम"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"लेख क्रियाएं"</string>
     <string name="email" msgid="4560673117055050403">"ईमेल करें"</string>
     <string name="dial" msgid="4204975095406423102">"फ़ोन"</string>
-    <string name="map" msgid="5441053548030107189">"मानचित्र"</string>
-    <string name="browse" msgid="6079864138582486027">"ब्राउज़ करें"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"मेमोरी स्‍थान समाप्‍त हो रहा है"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टम के लिए पर्याप्त मेमोरी नहीं है. सुनिश्चित करें कि आपके पास 250MB का खाली स्थान है और फिर से प्रारंभ करें."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3a11fe7..679bcd3 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -271,7 +271,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Izvođenje aplikacija u pozadini"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> izvodi se u pozadini"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije koje se izvode u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podataka"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Karta"</string>
-    <string name="browse" msgid="6079864138582486027">"Pregledaj"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda neće raditi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno pohrane za sustav. Oslobodite 250 MB prostora i pokrenite uređaj ponovo."</string>
@@ -1638,7 +1640,7 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Ažurirao administrator"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Izbrisao administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje performanse uređaja i ograničava vibraciju, lokacijske usluge i većinu pozadinskih radnji. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjila potrošnja podataka, Ušteda podataka onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Da bi se smanjio podatkovni promet, Ušteda podataka onemogućuje nekim aplikacijama slanje ili primanje podataka u pozadini. Aplikacija koju trenutačno upotrebljavate može pristupiti podacima, no možda će to činiti rjeđe. To može značiti da se, na primjer, slike neće prikazivati dok ih ne dodirnete."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Uključiti Uštedu podataka?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Uključi"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6da0f11..954d6e0 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kiskereskedelmi bemutató"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-kapcsolat"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"A háttérben még futnak alkalmazások"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás még fut a háttérben"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> a háttérben fut"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás még fut a háttérben"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Az akkumulátor töltöttségének és az adathasználat részleteinek megtekintéséhez koppintson"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Térkép"</string>
-    <string name="browse" msgid="6079864138582486027">"Böngészés"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kevés a szabad terület"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Előfordulhat, hogy néhány rendszerfunkció nem működik."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nincs elegendő tárhely a rendszerhez. Győződjön meg arról, hogy rendelkezik 250 MB szabad területtel, majd kezdje elölről."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index e2523a6..9f9e34c 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -154,7 +154,7 @@
     <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>. Չի վերահասցեավորվել"</string>
     <string name="fcComplete" msgid="3118848230966886575">"Հատկության կոդը ամբողջական է:"</string>
     <string name="fcError" msgid="3327560126588500777">"Կապի խնդիր կամ անվավեր գործառույթի կոդ:"</string>
-    <string name="httpErrorOk" msgid="1191919378083472204">"Լավ"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"Եղավ"</string>
     <string name="httpError" msgid="7956392511146698522">"Ցանցային սխալ էր տեղի ունեցել:"</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL-ը չհաջողվեց գտնել:"</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Կայքի նույնականացման սխեման չի աջակցվում:"</string>
@@ -209,7 +209,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Պատրաստվում է թարմացնել…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Թարմացման փաթեթի մշակում…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Վերագործարկում…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Գործարանային տվյալների վերականգնում"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Վերակայել բոլոր տվյալները"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Վերագործարկվում է…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Անջատվում է…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ձեր պլանշետը կանջատվի:"</string>
@@ -265,10 +265,10 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Խանութի ցուցադրական ռեժիմ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB կապակցում"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Հետին ֆոնին գործարկվող հավելվածներ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը գործարկվում է հետին ֆոնին"</string>
-    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելվածները գործարկվում են հետին ֆոնին"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Հպել՝ մարտկոցի և տվյալների օգտագործման մասին մանրամասներ ստանալու համար"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ն աշխատում է ֆոնային ռեժիմում"</string>
+    <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելված աշխատում են ֆոնում"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
@@ -957,7 +957,7 @@
     <string name="VideoView_error_title" msgid="3534509135438353077">"Տեսանյութի խնդիր"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Այս տեսանյութը հեռարձակման ենթակա չէ այս սարքով:"</string>
     <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Այս տեսանյութը հնարավոր չէ նվագարկել:"</string>
-    <string name="VideoView_error_button" msgid="2822238215100679592">"Լավ"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"Եղավ"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"կեսօր"</string>
     <string name="Noon" msgid="3342127745230013127">"Կեսօր"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Տեքստի գործողությունները"</string>
     <string name="email" msgid="4560673117055050403">"Էլփոստ"</string>
     <string name="dial" msgid="4204975095406423102">"Հեռախոս"</string>
-    <string name="map" msgid="5441053548030107189">"Քարտեզ"</string>
-    <string name="browse" msgid="6079864138582486027">"Բացել"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Հիշողությունը սպառվում է"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Որոշ գործառույթներ կարող են չաշխատել"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Համակարգի համար բավարար հիշողություն չկա: Համոզվեք, որ ունեք 250ՄԲ ազատ տարածություն և վերագործարկեք:"</string>
@@ -1026,12 +1028,12 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Ընտրել գործողություն"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Ընտրեք հավելված USB սարքի համար"</string>
     <string name="noApplications" msgid="2991814273936504689">"Ոչ մի հավելված չի կարող կատարել այս գործողությունը:"</string>
-    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածի աշխատանքն ընդհատվել է"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> – աշխատանքն ընդհատվեց"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացն ընդհատվել է"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածի աշխատանքը շարունակաբար ընդհատվում է"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը շարունակաբար ընդհատվում է"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Կրկին բացել հավելվածը"</string>
-    <string name="aerr_report" msgid="5371800241488400617">"Կարծիք հայտնել"</string>
+    <string name="aerr_report" msgid="5371800241488400617">"Հաղորդել"</string>
     <string name="aerr_close" msgid="2991640326563991340">"Փակել"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"Անջատել ձայնը մինչև սարքի վերագործարկումը"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"Սպասել"</string>
@@ -1041,7 +1043,7 @@
     <string name="anr_activity_process" msgid="1622382268908620314">"<xliff:g id="ACTIVITY">%1$s</xliff:g> գործունեությունը չի արձագանքում"</string>
     <string name="anr_application_process" msgid="6417199034861140083">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը չի արձագանքում"</string>
     <string name="anr_process" msgid="6156880875555921105">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը չի արձագանքում"</string>
-    <string name="force_close" msgid="8346072094521265605">"Լավ"</string>
+    <string name="force_close" msgid="8346072094521265605">"Հաստատել"</string>
     <string name="report" msgid="4060218260984795706">"Զեկույց"</string>
     <string name="wait" msgid="7147118217226317732">"Սպասեք"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Էջը չի պատասխանում:\n\nՑանկանու՞մ եք փակել այն:"</string>
@@ -1121,7 +1123,7 @@
     <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Թույլատրե՞լ կապը:"</string>
     <string name="wifi_connect_alert_message" msgid="6451273376815958922">"%1$s հավելվածը ցանկանում է միանալ %2$s Wifi ցանցին"</string>
     <string name="wifi_connect_default_application" msgid="7143109390475484319">"Հավելված"</string>
-    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ուղիղ"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Մեկնարկել Wi-Fi ուղին: Այն կանջատի Wi-Fi հաճախորդ/թեժ կետ գործողությունը:"</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Չհաջողվեց մեկնարկել Wi-Fi ուղին:"</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ուղիղն առցանց է"</string>
@@ -1170,7 +1172,7 @@
     <string name="perms_description_app" msgid="5139836143293299417">"Տրամադրված է <xliff:g id="APP_NAME">%1$s</xliff:g>-ի կողմից:"</string>
     <string name="no_permissions" msgid="7283357728219338112">"Թույլտվություններ չեն պահանջվում"</string>
     <string name="perm_costs_money" msgid="4902470324142151116">"Սա կարող է գումար պահանջել"</string>
-    <string name="dlg_ok" msgid="7376953167039865701">"Լավ"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Հաստատել"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"Սարքի լիցքավորում USB լարի միջոցով"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Հոսանքի մատակարարում կցված սարքերին USB լարի միջոցով"</string>
     <string name="usb_mtp_notification_title" msgid="8396264943589760855">"Ֆայլերի փոխանցման USB"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ի USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Աուդիո սարքը չի աջակցվում"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Հպեք՝ լրացուցիչ տեղեկություններ ստանալու համար"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Հպեք՝ USB վրիպազերծումն անջատելու համար:"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string>
@@ -1474,7 +1474,7 @@
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Հեռացնել"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ձայնը բարձրացնե՞լ խորհուրդ տրվող մակարդակից ավել:\n\nԵրկարատև բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Օգտագործե՞լ Մատչելիության դյուրանցումը։"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Եթե այս դյուրանցումը միացված է, ապա ձայնի ուժգնության երկու կոճակները 3 վայրկյանի ընթացքում միաժամանակ սեղմելու դեպքում կգործարկվի մատչելիության գործառույթը։\n\n Մատչելիության ակտիվ գործառույթը՝\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Կարող եք փոխել գործառույթը՝ անցնելով Կարգավորումներ &gt; Մատչելիություն։"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Մատչելիության գործառույթն օգտագործելու համար սեղմեք և 3 վայրկյան սեղմած պահեք ձայնի ուժգնության երկու կոճակները, երբ գործառույթը միացված է։\n\n Մատչելիության ակտիվ գործառույթը՝\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Գործառույթը կարող եք փոփոխել՝ անցնելով Կարգավորումներ &gt; Մատչելիություն։"</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Անջատել դյուրանցումը"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Օգտագործել դյուրանցումը"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Մատչելիության դյուրանցումն միացրել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
@@ -1617,8 +1617,8 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Տեղադրվել է ձեր ադմինիստրատորի կողմից"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Թարմացվել է ձեր ադմինիստրատորի կողմից"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Ջնջվել է ձեր ադմինիստրատորի կողմից"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Մարտկոցի աշխատանքի ժամկետը երկարացնելու համար տնտեսման ռեժիմում սահմանափակվում են սարքի արտադրողականությունը, թրթռոցը, տեղորոշման ծառայությունները և տվյալների ֆոնային փոխանցումը: Տվյալների համաժամեցումից կախված հավելվածները կարող են չթարմացվել, եթե դուք դրանք չգործարկեք:\n\n Մարտկոցի տնտեսման գործառույթն ավտոմատ կերպով անջատվում է սարքի լիցքավորման ժամանակ։"</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Տվյալների օգտագործումը նվազեցնելու նպատակով «Թրաֆիկի խնայումը» որոշ հավելվածներին թույլ չի տալիս ուղարկել կամ ստանալ տվյալներ ֆոնային ռեժիմում: Արդեն իսկ գործարկված հավելվածը կարող է օգտագործել տվյալները, սակայն ոչ այնքան հաճախ: Օրինակ՝ պատկերները կցուցադրվեն միայն դրանք հպելուց հետո:"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Մարտկոցի աշխատանքի ժամկետը երկարացնելու համար տնտեսման ռեժիմում սահմանափակվում են սարքի արտադրողականությունը, թրթռոցը, տեղորոշման ծառայությունները և տվյալների ֆոնային փոխանցումը: Տվյալների համաժամեցումից կախված հավելվածները կարող են չթարմացվել, եթե դուք դրանք չգործարկեք:\n\n Մարտկոցի տնտեսումն ավտոմատ կերպով անջատվում է սարքի լիցքավորման ժամանակ։"</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Թրաֆիկի տնտեսման ռեժիմում որոշ հավելվածների համար ֆոնային փոխանցումն անջատված է։ Հավելվածը, որն օգտագործում եք, կարող է տվյալներ փոխանցել և ստանալ, սակայն ոչ այնքան հաճախ: Օրինակ՝ պատկերները կցուցադրվեն միայն դրանց վրա սեղմելուց հետո։"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Միացնե՞լ թրաֆիկի խնայումը:"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Միացնել"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index f50a384..4719c51 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikasi yang sedang berjalan di latar belakang"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan di latar belakang"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang berjalan di latar belakang"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap untuk melihat detail baterai dan penggunaan data"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap untuk melihat detail penggunaan baterai dan data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
@@ -437,9 +437,9 @@
     <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Mengizinkan aplikasi untuk mengubah zona waktu TV."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Mengizinkan apl mengubah zona waktu pada ponsel."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"cari akun pada perangkat"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Memungkinkan aplikasi mendapatkan daftar akun yang dikenal oleh tablet. Ini mungkin termasuk akun yang dibuat oleh aplikasi yang telah Anda pasang."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Memungkinkan aplikasi mendapatkan daftar akun yang dikenal oleh tablet. Ini mungkin termasuk akun yang dibuat oleh aplikasi yang telah Anda instal."</string>
     <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Mengizinkan aplikasi untuk mendapatkan daftar akun yang dikenal oleh TV. Daftar ini mungkin meliputi akun yang dibuat oleh aplikasi yang telah dipasang."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Memungkinkan aplikasi mendapatkan daftar akun yang dikenal oleh ponsel. Ini mungkin termasuk akun yang dibuat oleh aplikasi yang telah Anda pasang."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Memungkinkan aplikasi mendapatkan daftar akun yang dikenal oleh ponsel. Ini mungkin termasuk akun yang dibuat oleh aplikasi yang telah Anda instal."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"lihat sambungan jaringan"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Memungkinkan aplikasi melihat informasi tentang sambungan jaringan, misalnya jaringan yang ada dan tersambung."</string>
     <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"dapatkan akses jaringan penuh"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Telepon"</string>
-    <string name="map" msgid="5441053548030107189">"Peta"</string>
-    <string name="browse" msgid="6079864138582486027">"Buka browser"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Penyimpanan tidak cukup untuk sistem. Pastikan Anda memiliki 250 MB ruang kosong, lalu mulai ulang."</string>
@@ -1243,7 +1245,7 @@
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Memungkinkan aplikasi menentukan rute keluaran media ke perangkat eksternal lainnya."</string>
     <string name="permlab_readInstallSessions" msgid="3713753067455750349">"baca sesi pemasangan"</string>
     <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Memungkinkan aplikasi membaca sesi pemasangan. Tindakan ini memungkinkannya melihat detail tentang pemasangan paket aktif."</string>
-    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"minta pasang paket"</string>
+    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"minta instal paket"</string>
     <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Mengizinkan aplikasi meminta pemasangan paket."</string>
     <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"meminta menghapus paket"</string>
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"Mengizinkan aplikasi meminta penghapusan paket."</string>
@@ -1654,7 +1656,7 @@
     <string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarm berikutnya)"</string>
     <string name="zen_mode_forever" msgid="1916263162129197274">"Hingga Anda menonaktifkan status Jangan Ganggu"</string>
-    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hingga Anda menonaktifkan status Jangan Ganggu"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Hingga status Jangan Ganggu dinonaktifkan"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"Jangan ganggu"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 281faf3..155f640 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaaðgerðir"</string>
     <string name="email" msgid="4560673117055050403">"Tölvupóstur"</string>
     <string name="dial" msgid="4204975095406423102">"Sími"</string>
-    <string name="map" msgid="5441053548030107189">"Kort"</string>
-    <string name="browse" msgid="6079864138582486027">"Vafri"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Geymslurýmið er senn á þrotum"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sumir kerfiseiginleikar kunna að vera óvirkir"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Ekki nægt geymslurými fyrir kerfið. Gakktu úr skugga um að 250 MB séu laus og endurræstu."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 9541111..44241ad 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -266,7 +266,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo retail"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connessione USB"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"App in esecuzione in background"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione in background"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione in background"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> app sono in esecuzione in background"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Azioni testo"</string>
     <string name="email" msgid="4560673117055050403">"Invia una email"</string>
     <string name="dial" msgid="4204975095406423102">"Telefono"</string>
-    <string name="map" msgid="5441053548030107189">"Mappa"</string>
-    <string name="browse" msgid="6079864138582486027">"Sfoglia"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spazio di archiviazione in esaurimento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Alcune funzioni di sistema potrebbero non funzionare"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Memoria insufficiente per il sistema. Assicurati di avere 250 MB di spazio libero e riavvia."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a087430..8b5db21 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -775,12 +775,12 @@
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"בטל נעילה"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"קול פועל"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ללא קול"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"יצירת התבנית החלה"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"התבנית נמחקה"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"יצירת הקו לביטול נעילה החלה"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"הקו לביטול נעילה נמחק"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"התא נוסף"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"תא <xliff:g id="CELL_INDEX">%1$s</xliff:g> נוסף"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"התבנית הושלמה"</string>
-    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"אזור ציור קו."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"הקו לביטול נעילה הושלם"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"אזור לשרטוט של קו ביטול הנעילה"</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"‏%1$s. Widget %2$d מתוך %3$d."</string>
     <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"‏הוסף Widget."</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ריק"</string>
@@ -796,11 +796,11 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"‏Widget ‏<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> נמחק."</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"הרחב את אזור ביטול הנעילה."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ביטול נעילה באמצעות הסטה."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ביטול נעילה באמצעות ציור קו."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ביטול נעילה על ידי שרטוט קו."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ביטול נעילה באמצעות זיהוי פנים."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ביטול נעילה באמצעות קוד גישה."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ביטול נעילה באמצעות סיסמה."</string>
-    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"אזור ציור קו."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"אזור לשרטוט קו ביטול נעילה."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"אזור הסטה."</string>
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"אבג"</string>
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
     <string name="email" msgid="4560673117055050403">"אימייל"</string>
     <string name="dial" msgid="4204975095406423102">"טלפון"</string>
-    <string name="map" msgid="5441053548030107189">"מפה"</string>
-    <string name="browse" msgid="6079864138582486027">"דפדף"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"שטח האחסון אוזל"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"‏אין מספיק שטח אחסון עבור המערכת. ודא שיש לך שטח פנוי בגודל 250MB התחל שוב."</string>
@@ -1116,7 +1118,7 @@
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> חורג מהגבלת הזיכרון"</string>
     <string name="dump_heap_notification_detail" msgid="6901391084243999274">"‏Dump של ערימה נאסף. הקש כדי לשתף"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"‏האם לשתף את נתוני ה-Dump של הערימה?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"‏התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת זיכרון התהליך שלו, בגודל <xliff:g id="SIZE">%2$s</xliff:g>. נתונים על Dump של ערימה זמינים לך לשיתוף עם המפתח של התהליך. היזהר: ה-Dump של הערימה יכול להכיל מידע אישי הזמין לאפליקציה."</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"‏התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת זיכרון התהליך שלו, בגודל <xliff:g id="SIZE">%2$s</xliff:g>. נתונים על Dump של ערימה זמינים לך לשיתוף עם המפתח של התהליך. זהירות: ה-Dump של הערימה יכול להכיל מידע אישי הזמין לאפליקציה."</string>
     <string name="sendText" msgid="5209874571959469142">"בחירת פעולה לביצוע עם טקסט"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"עוצמת קול של צלצול"</string>
     <string name="volume_music" msgid="5421651157138628171">"עוצמת קול של מדיה"</string>
@@ -1218,10 +1220,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏USB ל-MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏מחובר לאביזר USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"הקש לקבלת אפשרויות נוספות."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"אביזר אודיו אינו נתמך"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"הקש לקבלת מידע נוסף"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏הקש כדי להשבית ניפוי באגים של USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏בחר להשבית ניפוי באגים ב-USB."</string>
@@ -1339,7 +1339,7 @@
     <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
     <string name="back_button_label" msgid="2300470004503343439">"הקודם"</string>
     <string name="next_button_label" msgid="1080555104677992408">"הבא"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"דלג"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"דילוג"</string>
     <string name="no_matches" msgid="8129421908915840737">"אין התאמות"</string>
     <string name="find_on_page" msgid="1946799233822820384">"חפש בדף"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
@@ -1474,7 +1474,7 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"שכבת-על #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: ‎<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>‎, ‏<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", מאובטח"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"שכחת את הקו"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"שכחת את קו ביטול הנעילה?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"קו ביטול נעילה שגוי"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"סיסמה שגויה"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"קוד גישה שגוי"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2c1b9f4..8e68ea2 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"バックグラウンドで実行中のアプリ"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」がバックグラウンドで実行中です"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリがバックグラウンドで実行中です"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"タップすると、電池やデータの使用量を詳しく確認できます"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"タップして電池やデータの使用量を確認"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"テキスト操作"</string>
     <string name="email" msgid="4560673117055050403">"メール"</string>
     <string name="dial" msgid="4204975095406423102">"電話"</string>
-    <string name="map" msgid="5441053548030107189">"地図"</string>
-    <string name="browse" msgid="6079864138582486027">"ブラウジング"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"空き容量わずか"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"一部のシステム機能が動作しない可能性があります"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"システムに十分な容量がありません。250MBの空き容量を確保して再起動してください。"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"タップしてその他のオプションを表示します。"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"オーディオ アクセサリがサポートされていません"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"タップして詳細をご確認ください"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"タップして USB デバッグを無効にします。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index d7183bc..895f8ae 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ქმედებები ტექსტზე"</string>
     <string name="email" msgid="4560673117055050403">"ელფოსტა"</string>
     <string name="dial" msgid="4204975095406423102">"ტელეფონი"</string>
-    <string name="map" msgid="5441053548030107189">"რუკა"</string>
-    <string name="browse" msgid="6079864138582486027">"მოძიება"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"თავისუფალი ადგილი იწურება"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"სისტემის ზოგიერთმა ფუნქციამ შესაძლოა არ იმუშავოს"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"სისტემისათვის საკმარისი საცავი არ არის. დარწმუნდით, რომ იქონიოთ სულ მცირე 250 მბაიტი თავისუფალი სივრცე და დაიწყეთ ხელახლა."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 842cd3a..1bd9784 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Бөлшек саудаға арналған демо нұсқасы"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB байланысы"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фонда жұмыс істеп тұрған қолданбалар"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы фонда жұмыс істеп тұр"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> фонда жұмыс істеп тұр"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба фонда жұмыс істеп тұр"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батарея мен деректер трафигі туралы мәліметтер алу үшін түртіңіз"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android жүйесі"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Мәтін әрекеттері"</string>
     <string name="email" msgid="4560673117055050403">"Электрондық пошта"</string>
     <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="5441053548030107189">"Map"</string>
-    <string name="browse" msgid="6079864138582486027">"Шолу"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Жадта орын азайып барады"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Жүйенің кейбір функциялары жұмыс істемеуі мүмкін"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Жүйе үшін жад жеткіліксіз. 250 МБ бос орын бар екенін тексеріп, қайта іске қосыңыз."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI режиміне арналған USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB жабдығына қосылған"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Қосымша опциялар үшін түртіңіз."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио аксессуарға қолдау көрсетілмейді"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Қосымша ақпарат алу үшін түртіңіз"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB түзетуін өшіру үшін түртіңіз."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index a42f777..af442d8 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"កម្មវិធី <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ចុចដើម្បីទទួលបានព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ថ្ម និងទិន្នន័យ"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"របៀប​​​សុវត្ថិភាព"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ​​ Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាព​អត្ថបទ"</string>
     <string name="email" msgid="4560673117055050403">"អ៊ីមែល"</string>
     <string name="dial" msgid="4204975095406423102">"ទូរសព្ទ"</string>
-    <string name="map" msgid="5441053548030107189">"ផែនទី"</string>
-    <string name="browse" msgid="6079864138582486027">"រុក​រក"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់​ទំហំ​ផ្ទុក"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ​"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"មិន​មាន​ទំហំ​ផ្ទុក​​គ្រប់​គ្រាន់​សម្រាប់​ប្រព័ន្ធ​។ សូម​ប្រាកដ​ថា​អ្នក​មាន​ទំហំ​ទំនេរ​ 250MB ហើយ​ចាប់ផ្ដើម​ឡើង​វិញ។"</string>
@@ -1180,10 +1182,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB សម្រាប់ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"មិនស្គាល់គ្រឿងបរិក្ខារសំឡេងទេ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ចុចដើម្បីទទួលព័ត៌មានបន្ថែម"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"ប៉ះដើម្បីបិទដំណើរការកែកំហុសយូអេសប៊ី"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស​ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fbd51b9..51940e4 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ರಿಟೇಲ್ ಡೆಮೋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ಸಂಪರ್ಕ"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ಬ್ಯಾಟರಿ ಮತ್ತು ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android ಸಿಸ್ಟಂ"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ಪಠ್ಯದ ಕ್ರಮಗಳು"</string>
     <string name="email" msgid="4560673117055050403">"ಇಮೇಲ್"</string>
     <string name="dial" msgid="4204975095406423102">"ಫೋನ್"</string>
-    <string name="map" msgid="5441053548030107189">"ನಕ್ಷೆ"</string>
-    <string name="browse" msgid="6079864138582486027">"ಬ್ರೌಸ್ ಮಾಡಿ"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ಸಂಗ್ರಹಣೆ ಸ್ಥಳವು ತುಂಬಿದೆ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ಕೆಲವು ಸಿಸ್ಟಂ ಕಾರ್ಯವಿಧಾನಗಳು ಕಾರ್ಯನಿರ್ವಹಿಸದೇ ಇರಬಹುದು"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ಸಿಸ್ಟಂನಲ್ಲಿ ಸಾಕಷ್ಟು ಸಂಗ್ರಹಣೆಯಿಲ್ಲ. ನೀವು 250MB ನಷ್ಟು ಖಾಲಿ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುವಿರಾ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ ಹಾಗೂ ಮರುಪ್ರಾರಂಭಿಸಿ."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ಗೆ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ಪರಿಕರಕ್ಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ಆಡಿಯೋ ಪರಿಕರಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index bbddc24..d939f2a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"백그라운드에서 실행 중인 앱"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱이 백그라운드에서 실행 중"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g>개의 앱이 백그라운드에서 실행 중"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"탭하여 배터리 및 데이터 사용량에 관한 세부정보 보기"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"탭하여 배터리 및 데이터 사용량 확인"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
     <string name="email" msgid="4560673117055050403">"이메일"</string>
     <string name="dial" msgid="4204975095406423102">"전화"</string>
-    <string name="map" msgid="5441053548030107189">"지도"</string>
-    <string name="browse" msgid="6079864138582486027">"탐색"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"저장 공간이 부족함"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"시스템의 저장 공간이 부족합니다. 250MB의 여유 공간이 확보한 후 다시 시작하세요."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI용 USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"옵션을 더 보려면 탭하세요."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"지원되지 않는 오디오 액세서리"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"자세한 내용은 탭하여 확인하세요."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB 디버깅을 사용하지 않으려면 탭하세요."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f5f48ad..82982b5 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Чекене соода дүкөнү үчүн демо режим"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB аркылуу туташуу"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фондо иштеп жаткан колдонмолор"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу фондо иштөөдө"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу фондо иштеп жатат"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо фондо иштөөдө"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батареянын кубаты жана Интернеттин колдонулушу жөнүндө билүү үчүн таптап коюңуз"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android тутуму"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст боюнча иштер"</string>
     <string name="email" msgid="4560673117055050403">"Электрондук почта"</string>
     <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Карап чыгуу"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сактагычта орун калбай баратат"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Системанын кээ бир функциялары иштебеши мүмкүн"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Тутумда сактагыч жетишсиз. 250МБ бош орун бар экенин текшерип туруп, өчүрүп күйгүзүңүз."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI үчүн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB аксессуарга байланышты"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио шайманы колдоого алынбайт"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Мүчүлштктрдү USB аркл оңдну өчр үчн тийп коюңуз."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1619,7 +1619,7 @@
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Администраторуңуз жаңыртып койгон"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Администраторуңуз жок кылып салган"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Батареянын өмүрүн узартуу үчүн, кубатты үнөмдөө режими түзмөгүңүздүн ишин солгундатып, дирилдөө функциясын, жайгашкан жерди аныктоо кызматын жана дайындардын фондо өткөрүлүшүн чектеп коёт. Электрондук почта, билдирүү жазышуу сыяктуу шайкештириле турган дайындар колдонмо ачылганда гана жаңырат.\n\nБатареянын кубатын үнөмдөө режими түзмөгүңүз кубатталып жатканда автоматтык түрдө өчүп калат."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Трафиктин колдонулушун үнөмдөө режиминде айрым колдонмолор дайындарды фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайындарды өткөрөт, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары башкача иштеши мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Трафикти үнөмдөө режиминде айрым колдонмолор дайындарды фондо өткөрө алышпайт. Учурда сиз пайдаланып жаткан колдонмо дайындарды жөнөтүп/ала алат, бирок адаттагыдан азыраак өткөргөндүктөн, анын айрым функциялары талаптагыдай иштебей коюшу мүмкүн. Мисалы, сүрөттөр басылмайынча жүктөлбөйт."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Дайындарды үнөмдөгүч күйсүнбү?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Күйгүзүү"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index bf1ef11..5e536b9 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
     <string name="email" msgid="4560673117055050403">"ອີເມວ"</string>
     <string name="dial" msgid="4204975095406423102">"ໂທລະສັບ"</string>
-    <string name="map" msgid="5441053548030107189">"ແຜນທີ່"</string>
-    <string name="browse" msgid="6079864138582486027">"ເລືອກເບິ່ງ"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ການເຮັດວຽກບາງຢ່າງຂອງລະບົບບາງອາດຈະໃຊ້ບໍ່ໄດ້"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"​ບໍ່​ມີ​ບ່ອນ​ເກັບ​ຂໍ້​ມູນ​ພຽງ​ພໍ​ສຳ​ລັບ​ລະ​ບົບ. ກວດ​ສອບ​ໃຫ້​ແນ່​ໃຈ​ວ່າ​ທ່ານ​ມີ​ພື້ນ​ທີ່​ຫວ່າງ​ຢ່າງ​ໜ້ອຍ 250MB ​ແລ້ວລອງ​ໃໝ່."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB ສຳ​ລັບ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ບໍ່ຮອງຮັບອຸປະກອນເສີມສຽງ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"ແຕະເພື່ອປິດການດີບັກຜ່ານ USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
@@ -1617,7 +1617,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"ຖືກຕິດຕັ້ງໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"ຖືກອັບໂຫລດໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ຖືກລຶບອອກໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"ເພື່ອ​ຊ່ວຍ​ເພີ່ມ​ອາ​ຍຸ​ແບັດ​ເຕີ​ຣີ, ຕົວ​ປະ​ຢັດ​ໄຟ​ແບັດ​ເຕີ​ຣີ​ຫຼຸດ​ປະ​ສິດ​ທິ​ພາບ​ການ​ເຮັດ​ວຽກ​ຂອງ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ລົງ ແລະ​ຈຳ​ກັດ​ການ​ສັ່ນ, ການ​ບໍ​ລິ​ການ​ຫາທີ່ຕັ້ງ ແລະ ຂໍ້​ມູນ​ພື້ນ​ຫຼັງ​ເກືອບ​ທັງ​ໝົດ. ອີ​ເມວ, ການ​ສົ່ງ​ຂໍ້​ຄວາມ, ແລະ ແອັບອື່ນໆ​ທີ່ອາ​ໄສການ​ຊິ້ງຂໍ້ມູນ​ອາດ​ຈະ​ບໍ່​ອັບ​ເດດ ນອກ​ຈາກວ່າ​ທ່ານ​ເປີດ​ມັນ.\n\nຕົວ​ປະ​ຢັດ​ໄຟ​ແບັດ​ເຕີ​ຣີຈະ​ປິດ​ອັດ​ຕະ​ໂນ​ມັດເມື່ອ​ທ່ານສາກໄຟອຸ​ປະ​ກອນ​."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ເພື່ອຊ່ວຍເພີ່ມອາຍຸແບັດເຕີຣີ, ຕົວປະຢັດໄຟແບັດເຕີຣີຫຼຸດປະສິດທິພາບການເຮັດວຽກຂອງອຸປະກອນຂອງທ່ານລົງ ແລະຈຳກັດການສັ່ນ, ບໍລິການສະຖານທີ່ ແລະ ຂໍ້ມູນພື້ນຫຼັງເກືອບທັງໝົດ. ອີເມວ, ການສົ່ງຂໍ້ຄວາມ ແລະ ແອັບອື່ນໆທີ່ອາໄສການຊິ້ງຂໍ້ມູນອາດຈະບໍ່ອັບເດດ ນອກຈາກວ່າທ່ານເປີດມັນ.\n\nຕົວປະຢັດໄຟແບັດເຕີຣີຈະປິດອັດຕະໂນມັດເມື່ອທ່ານສາກໄຟອຸປະກອນ."</string>
     <string name="data_saver_description" msgid="6015391409098303235">"ເພື່ອຊ່ວຍຫຼຸດຜ່ອນການນຳໃຊ້ຂໍ້ມູນ, ຕົວປະຢັດຂໍ້ມູນຈະປ້ອງກັນບໍ່ໃຫ້ບາງແອັບສົ່ງ ຫຼື ຮັບຂໍ້ມູນໃນພື້ນຫຼັງ. ແອັບໃດໜຶ່ງທີ່ທ່ານກຳລັງໃຊ້ຢູ່ຈະສາມາດເຂົ້າເຖິງຂໍ້ມູນໄດ້ ແຕ່ອາດເຂົ້າເຖິງໄດ້ຖີ່ໜ້ອຍລົງ. ນີ້ອາດໝາຍຄວາມວ່າ ຮູບພາບຕ່າງໆອາດບໍ່ສະແດງຈົນກວ່າທ່ານຈະແຕະໃສ່ກ່ອນ."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ເປີດໃຊ້ຕົວປະຢັດຂໍ້ມູນບໍ?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ເປີດໃຊ້"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d8c292e..dce8df4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
     <string name="email" msgid="4560673117055050403">"Siųsti el. laišką"</string>
     <string name="dial" msgid="4204975095406423102">"Telefonas"</string>
-    <string name="map" msgid="5441053548030107189">"Žemėlapis"</string>
-    <string name="browse" msgid="6079864138582486027">"Naršyti"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Mažėja laisvos saugyklos vietos"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kai kurios sistemos funkcijos gali neveikti"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistemos saugykloje nepakanka vietos. Įsitikinkite, kad yra 250 MB laisvos vietos, ir paleiskite iš naujo."</string>
@@ -1066,7 +1068,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Pasirinkti veiksmą"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Pasirinkite USB įrenginio programą"</string>
     <string name="noApplications" msgid="2991814273936504689">"Jokios programos negali atlikti šio veiksmo."</string>
-    <string name="aerr_application" msgid="250320989337856518">"„<xliff:g id="APPLICATION">%1$s</xliff:g>“ sustabdyta"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> sustabdyta"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> sustabdytas"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"„<xliff:g id="APPLICATION">%1$s</xliff:g>“ vis sustabdoma"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"Procesas „<xliff:g id="PROCESS">%1$s</xliff:g>“ vis sustabdomas"</string>
@@ -1218,10 +1220,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB (MIDI)"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Prijungta prie USB priedo"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Garso įrašo priedas nepalaikomas"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Palieskite, kad išjungtumėte USB derinimą."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 68a2299..b38837d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
     <string name="email" msgid="4560673117055050403">"E-pasts"</string>
     <string name="dial" msgid="4204975095406423102">"Tālrunis"</string>
-    <string name="map" msgid="5441053548030107189">"Maps"</string>
-    <string name="browse" msgid="6079864138582486027">"Pārlūkot"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Paliek maz brīvas vietas"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Dažas sistēmas funkcijas var nedarboties."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistēmai pietrūkst vietas. Atbrīvojiet vismaz 250 MB vietas un restartējiet ierīci."</string>
@@ -1198,10 +1200,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB savienojums MIDI režīmā"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Pieskarieties, lai skatītu citas iespējas."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Audio piederums netiek atbalstīts"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Pieskarieties, lai uzzinātu vairāk"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Pieskarieties, lai atspējotu USB atkļūdošanu."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
diff --git a/core/res/res/values-mcc505-mnc01/config.xml b/core/res/res/values-mcc505-mnc01/config.xml
index 1705e4a..ff06585 100644
--- a/core/res/res/values-mcc505-mnc01/config.xml
+++ b/core/res/res/values-mcc505-mnc01/config.xml
@@ -40,6 +40,16 @@
       <item>Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</item>
     </string-array>
 
+    <!--Thresholds for LTE dbm in status bar-->
+    <integer-array translatable="false" name="config_lteDbmThresholds">
+        <item>-140</item>    <!-- SIGNAL_STRENGTH_NONE_OR_UNKNOWN -->
+        <item>-120</item>    <!-- SIGNAL_STRENGTH_POOR -->
+        <item>-115</item>    <!-- SIGNAL_STRENGTH_MODERATE -->
+        <item>-100</item>    <!-- SIGNAL_STRENGTH_GOOD -->
+        <item>-90</item>     <!-- SIGNAL_STRENGTH_GREAT -->
+        <item>-44</item>
+    </integer-array>
+
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
     <integer name="config_mobile_mtu">1400</integer>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index ae79a4a..c7098d6 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -59,12 +59,12 @@
     <string name="mismatchPin" msgid="609379054496863419">"Впишаните PIN-броеви не се совпаѓаат."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Внеси PIN од 4 до 8 броеви."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"Внеси ПУК од 8 броеви или повеќе."</string>
-    <string name="needPuk" msgid="919668385956251611">"Вашата СИМ картичка е заклучена со ПУК код. Внесете го ПУК кодот за да се отклучи."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"Внесете го ПУК2 кодот за да се одблокира СИМ картичката."</string>
+    <string name="needPuk" msgid="919668385956251611">"Вашата SIM картичка е заклучена со ПУК код. Внесете го ПУК кодот за да се отклучи."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Внесете го ПУК2 кодот за да се одблокира SIM картичката."</string>
     <string name="enablePin" msgid="209412020907207950">"Неуспешно, овозможи заклучување на SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
-      <item quantity="one">Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обид пред СИМ-картичката да се заклучи.</item>
-      <item quantity="other">Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обиди пред СИМ-картичката да се заклучи.</item>
+      <item quantity="one">Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обид пред SIM-картичката да се заклучи.</item>
+      <item quantity="other">Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обиди пред SIM-картичката да се заклучи.</item>
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
@@ -402,8 +402,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Овозможува апликацијата да ги менува глобалните аудио поставки, како што се јачината на звукот и кој звучник се користи за излез."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"снимај аудио"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Апликацијава може да снима аудио со микрофонот во секое време."</string>
-    <string name="permlab_sim_communication" msgid="2935852302216852065">"испраќање наредби до СИМ-картичката"</string>
-    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Овозможува апликацијата да испраќа наредби до СИМ картичката. Ова е многу опасно."</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"испраќање наредби до SIM-картичката"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Овозможува апликацијата да испраќа наредби до SIM картичката. Ова е многу опасно."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"снимај слики и видеа"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Апликацијава може да фотографира и да снима видеа со камерата во секое време."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"контролирај вибрации"</string>
@@ -501,18 +501,18 @@
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Овозможува апликацијата да ги менува поставките за синхронизирање на сметка. На пример, ова може да се употреби да овозможи синхронизација на апликацијата „Луѓе“ со сметка."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"читај статистика за синхронизација"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Овозможува апликацијата да ја чита статистиката за синхронизација на сметка, вклучувајќи ја и историјата на синхронизирани настани и колку податоци се синхронизирани."</string>
-    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"прочитај ги содржините на твојата УСБ меморија"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"прочитај ги содржините на твојата USB меморија"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"прочитај ги содржините на твојата СД картичка"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Овозможува апликацијата да ги чита содржините од вашето УСБ."</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Овозможува апликацијата да ги чита содржините од вашето USB."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Овозможува апликацијата да ги чита содржините од вашата СД картичка."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"измени ги или избриши ги содржините на твојата УСБ меморија"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"измени ги или избриши ги содржините на твојата USB меморија"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"измени ги или избриши ги содржините на твојата СД картичка"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дозволува пишување на УСБ-склад."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дозволува пишување на USB-склад."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозволува апликацијата да пишува на СД-картичката."</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"остварува/прима повици преку SIP"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"Дозволува апликацијата да остварува и прима повици преку SIP."</string>
-    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"регистрира нови телекомуникациски врски преку СИМ"</string>
-    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Дозволува апликацијата да регистрира нови телекомуникациски врски преку СИМ."</string>
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"регистрира нови телекомуникациски врски преку SIM"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Дозволува апликацијата да регистрира нови телекомуникациски врски преку SIM."</string>
     <string name="permlab_register_call_provider" msgid="108102120289029841">"регистрира нови телекомуникациски врски"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Дозволува апликацијата да регистрира нови телекомуникациски врски."</string>
     <string name="permlab_connection_manager" msgid="1116193254522105375">"управува со телекомуникациски врски"</string>
@@ -722,14 +722,14 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Обидете се повторно"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Отклучи за сите функции и податоци"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Максималниот број обиди на отклучување со лице е надминат"</string>
-    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Нема СИМ картичка"</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Во таблетот нема СИМ картичка."</string>
-    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Нема СИМ-картичка во телевизорот."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Во телефонот нема СИМ картичка."</string>
-    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Вметнете СИМ-картичка."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Нема СИМ-картичка или не може да се прочита. Вметнете СИМ-картичка."</string>
-    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Неупотреблива СИМ картичка."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Вашата СИМ-картичка е трајно оневозможена.\nКонтактирајте со давателот на услуги за безжична мрежа за друга СИМ-картичка."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Нема SIM картичка"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Во таблетот нема SIM картичка."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Нема SIM-картичка во телевизорот."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Во телефонот нема SIM картичка."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Вметнете SIM-картичка."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Нема SIM-картичка или не може да се прочита. Вметнете SIM-картичка."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Неупотреблива SIM картичка."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Вашата SIM-картичка е трајно оневозможена.\nКонтактирајте со давателот на услуги за безжична мрежа за друга SIM-картичка."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Претходна песна"</string>
     <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Следна песна"</string>
     <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Пауза"</string>
@@ -739,10 +739,10 @@
     <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Брзо премотај напред"</string>
     <string name="emergency_calls_only" msgid="6733978304386365407">"Само повици за итни случаи"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Мрежата е заклучена"</string>
-    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"СИМ картичката е заклучена со ПУК код."</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM картичката е заклучена со ПУК код."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Погледнете го Упатството за корисници или контактирајте со Грижа за корисници."</string>
-    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"СИМ картичката е заклучена."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"СИМ картичката се отклучува..."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM картичката е заклучена."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM картичката се отклучува..."</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Погрешно сте ја употребиле вашата шема за отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Погрешно сте ја впишале вашата лозинка <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Погрешно сте го впишале вашиот PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дејства со текст"</string>
     <string name="email" msgid="4560673117055050403">"E-пошта"</string>
     <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Прелистувајте"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Меморијата е речиси полна"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некои системски функции може да не работат"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Нема доволно меморија во системот. Проверете дали има слободен простор од 250 МБ и рестартирајте."</string>
@@ -1024,7 +1026,7 @@
     <string name="use_a_different_app" msgid="8134926230585710243">"Користи различна апликација"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Избриши ги стандардните вредности во Системски поставки &gt; Апликации &gt; Преземено."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Избери дејство"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Изберете апликација за УСБ-уредот"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Изберете апликација за USB-уредот"</string>
     <string name="noApplications" msgid="2991814273936504689">"Нема апликации што можат да го извршат ова дејство."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> запре"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> запре"</string>
@@ -1151,16 +1153,16 @@
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Може да го променш ова подоцна во Поставувања &gt; Апликации"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Секогаш дозволувај"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Никогаш не дозволувај"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"СИМ картичката е отстранета"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"Мобилната мрежа ќе биде недостапна додека се рестартира со вметната важечка СИМ картичка."</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM картичката е отстранета"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Мобилната мрежа ќе биде недостапна додека се рестартира со вметната важечка SIM картичка."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
-    <string name="sim_added_title" msgid="3719670512889674693">"Додадена е СИМ картичка"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"Додадена е SIM картичка"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Рестартирај го својот уред за да пристапиш на мобилната мрежа."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Рестартирај"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"За да работи правилно вашата нова СИМ-картичка, треба да ја инсталирате и да ја отворите апликацијата од операторот."</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"За да работи правилно вашата нова SIM-картичка, треба да ја инсталирате и да ја отворите апликацијата од операторот."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"ПРЕЗЕМИ ЈА АПЛИКАЦИЈАТА"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"НЕ СЕГА"</string>
-    <string name="carrier_app_notification_title" msgid="8921767385872554621">"Вметната е нова СИМ-картичка"</string>
+    <string name="carrier_app_notification_title" msgid="8921767385872554621">"Вметната е нова SIM-картичка"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Допрете за да поставите"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Постави време"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Постави датум"</string>
@@ -1173,16 +1175,14 @@
     <string name="dlg_ok" msgid="7376953167039865701">"Во ред"</string>
     <string name="usb_charging_notification_title" msgid="6895185153353640787">"Уредов се полни преку USB"</string>
     <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Прикачениот уред се напојува преку USB"</string>
-    <string name="usb_mtp_notification_title" msgid="8396264943589760855">"УСБ за пренос на датотеки"</string>
-    <string name="usb_ptp_notification_title" msgid="1347328437083192112">"УСБ за пренос на фотографии"</string>
-    <string name="usb_midi_notification_title" msgid="4850904915889144654">"УСБ за МИДИ"</string>
-    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со УСБ додаток"</string>
+    <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB за пренос на датотеки"</string>
+    <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB за пренос на фотографии"</string>
+    <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB за МИДИ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со USB додаток"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Допрете за повеќе опции."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string>
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиододатокот не е поддржан"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Допрете за повеќе информации"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
     <skip />
@@ -1308,7 +1308,7 @@
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> од <xliff:g id="TOTAL">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"Готово"</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Бришење УСБ меморија..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Бришење USB меморија..."</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"Бришење СД картичка..."</string>
     <string name="share" msgid="1778686618230011964">"Сподели"</string>
     <string name="find" msgid="4808270900322985960">"Пронајди"</string>
@@ -1369,9 +1369,9 @@
     <string name="storage_internal" msgid="3570990907910199483">"Внатрешно заедничко место за складирање"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"СД картичка"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> СД-картичка"</string>
-    <string name="storage_usb_drive" msgid="6261899683292244209">"УСБ-меморија"</string>
-    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> УСБ-меморија"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"УСБ меморија"</string>
+    <string name="storage_usb_drive" msgid="6261899683292244209">"USB-меморија"</string>
+    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB-меморија"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB меморија"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Измени"</string>
     <string name="data_usage_warning_title" msgid="3620440638180218181">"Известување за потрошен сообраќај"</string>
     <string name="data_usage_warning_body" msgid="6660692274311972007">"Допрете за употреба и поставки."</string>
@@ -1441,17 +1441,17 @@
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Погрешен PIN"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Обидете се повторно за <xliff:g id="NUMBER">%1$d</xliff:g> секунди."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Употреби ја својата шема"</string>
-    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Внеси PIN на СИМ картичка"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Внеси PIN на SIM картичка"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Внеси PIN"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"Внеси лозинка"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"СИМ картичката е сега оневозможена. Внесете ПУК код за да продолжите. Контактирајте го операторот за детали."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM картичката е сега оневозможена. Внесете ПУК код за да продолжите. Контактирајте го операторот за детали."</string>
     <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Внеси посакуван PIN код"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Потврди го саканиот PIN код"</string>
-    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"СИМ картичката се отклучува..."</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картичката се отклучува..."</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Погрешен PIN код."</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Внесете PIN кој содржи 4-8 броеви."</string>
     <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"ПУК кодот треба да има 8 броеви."</string>
-    <string name="kg_invalid_puk" msgid="3638289409676051243">"Повторно внесете го точниот ПУК код. Повторните обиди трајно ќе ја оневозможат СИМ картичката."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Повторно внесете го точниот ПУК код. Повторните обиди трајно ќе ја оневозможат SIM картичката."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодовите не се совпаѓаат"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Премногу обиди со шема"</string>
     <string name="kg_login_instructions" msgid="1100551261265506448">"За да го отклучите, најавете се со вашата сметка на Google."</string>
@@ -1680,9 +1680,9 @@
     <string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Прошири"</string>
     <string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Собери"</string>
     <string name="expand_action_accessibility" msgid="5307730695723718254">"вклучи/исклучи проширување"</string>
-    <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Надворешна порта на УСБ за Android"</string>
+    <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Надворешна порта на USB за Android"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
-    <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Надворешна порта на УСБ"</string>
+    <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Надворешна порта на USB"</string>
     <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Повеќе опции"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Затвори прелевање"</string>
     <string name="maximize_button_text" msgid="7543285286182446254">"Зголеми"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c1fc989..c479fb1 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ടെക്‌സ്‌റ്റ് പ്രവർത്തനങ്ങൾ"</string>
     <string name="email" msgid="4560673117055050403">"ഇമെയിൽ"</string>
     <string name="dial" msgid="4204975095406423102">"ഫോണ്‍"</string>
-    <string name="map" msgid="5441053548030107189">"മാപ്പ്"</string>
-    <string name="browse" msgid="6079864138582486027">"ബ്രൗസുചെയ്യുക"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"സംഭരണയിടം കഴിഞ്ഞു"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ചില സിസ്റ്റം പ്രവർത്തനങ്ങൾ പ്രവർത്തിക്കണമെന്നില്ല."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"സിസ്‌റ്റത്തിനായി മതിയായ സംഭരണമില്ല. 250MB സൗജന്യ സംഭരണമുണ്ടെന്ന് ഉറപ്പുവരുത്തി പുനരാരംഭിക്കുക."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-യ്‌ക്കായുള്ള USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ഒരു USB ആക്‌സസ്സറി കണക്റ്റുചെയ്‌തു"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ഓഡിയോ ആക്‌സസറി പ്രവർത്തിക്കുകയില്ല"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പുചെയ്യുക"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 3913964..69fb07f 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Жижиглэнгийн жишээ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB холболт"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Цаана ажиллаж буй апп"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> цаана ажиллаж байна"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ард ажиллаж байна"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> апп цаана ажиллаж байна"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батерей, дата ашиглалтын талаар дэлгэрэнгүй мэдээллийг харахын тулд товшино уу"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст үйлдэл"</string>
     <string name="email" msgid="4560673117055050403">"Имэйл"</string>
     <string name="dial" msgid="4204975095406423102">"Утас"</string>
-    <string name="map" msgid="5441053548030107189">"Газрын зураг"</string>
-    <string name="browse" msgid="6079864138582486027">"Хөтлөх"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сангийн хэмжээ дутагдаж байна"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Зарим систем функц ажиллахгүй байна"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Системд хангалттай сан байхгүй байна. 250MБ чөлөөтэй зай байгаа эсэхийг шалгаад дахин эхлүүлнэ үү."</string>
@@ -1035,7 +1037,7 @@
     <string name="aerr_close" msgid="2991640326563991340">"Хаах"</string>
     <string name="aerr_mute" msgid="1974781923723235953">"Төхөөрөмжийг дахин эхлүүлэх хүртэл дууг нь хаах"</string>
     <string name="aerr_wait" msgid="3199956902437040261">"Хүлээх"</string>
-    <string name="aerr_close_app" msgid="3269334853724920302">"Апп-ыг хаах"</string>
+    <string name="aerr_close_app" msgid="3269334853724920302">"Аппыг хаах"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="8493290105678066167">"<xliff:g id="APPLICATION">%2$s</xliff:g> хариу өгөхгүй байна"</string>
     <string name="anr_activity_process" msgid="1622382268908620314">"<xliff:g id="ACTIVITY">%1$s</xliff:g> хариу өгөхгүй байна"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI-ийн USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Бусад сонголтыг харахын тулд товшино уу."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудио хэрэгслийг дэмжээгүй байна"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Дэлгэрэнгүйг үзэхийн тулд товшино уу"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB-н алдаа засварлахыг идэвхгүй болгохын тулд товшино уу."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 1801664..b29a4d9 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"मजकूर क्रिया"</string>
     <string name="email" msgid="4560673117055050403">"ईमेल"</string>
     <string name="dial" msgid="4204975095406423102">"फोन"</string>
-    <string name="map" msgid="5441053548030107189">"नकाशा"</string>
-    <string name="browse" msgid="6079864138582486027">"ब्राउझ करा"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"संचयन स्थान संपत आहे"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"काही सिस्टम कार्ये कार्य करू शकत नाहीत"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"सिस्टीमसाठी पुरेसे संचयन नाही. आपल्याकडे 250MB मोकळे स्थान असल्याचे सुनिश्चित करा आणि रीस्टार्ट करा."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI साठी USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB उपसाधनावर कनेक्ट केले"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"अधिक पर्यायांसाठी टॅप करा."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ऑडिओ अॅक्‍सेसरी समर्थित नाही"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"आणखी माहितीसाठी येथे टॅप करा"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डीबग करणे अक्षम करण्यासाठी टॅप करा."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 27095c5..265788c 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="email" msgid="4560673117055050403">"E-mel"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Peta"</string>
-    <string name="browse" msgid="6079864138582486027">"Semak imbas"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tidak cukup storan untuk sistem. Pastikan anda mempunyai 250MB ruang kosong dan mulakan semula."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Ketik untuk mendapatkan lagi pilihan."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori audio tidak disokong"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Ketik untuk mendapatkan maklumat lanjut"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Ketik untuk melumpuhkan penyahpepijatan USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 5d97ba8..5231762 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -251,7 +251,7 @@
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
     <string name="notification_hidden_text" msgid="1135169301897151909">"အကြောင်းအရာများ ဝှက်ထား"</string>
     <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"မူဝါဒမှ အကြောင်းအရာများကို ဝှက်ထားသည်"</string>
-    <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ကီးဘုတ်အတု"</string>
+    <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"ပကတိအသွင်ကီးဘုတ်"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"ကီးဘုတ် ခလုတ်ခုံ"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"လုံခြုံရေး"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ကားမုဒ်"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"စာတို လုပ်ဆောင်ချက်"</string>
     <string name="email" msgid="4560673117055050403">"အီးမေးလ်"</string>
     <string name="dial" msgid="4204975095406423102">"ဖုန်း"</string>
-    <string name="map" msgid="5441053548030107189">"မြေပုံ"</string>
-    <string name="browse" msgid="6079864138582486027">"အကြမ်းဖျင်း ကြည့်ရန်"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"သိမ်းဆည်သော နေရာ နည်းနေပါသည်"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"တချို့ စနစ်လုပ်ငန်းများ အလုပ် မလုပ်ခြင်း ဖြစ်နိုင်ပါသည်"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"စနစ်အတွက် သိုလှောင်ခန်း မလုံလောက်ပါ။ သင့်ဆီမှာ နေရာလွတ် ၂၅၀ MB ရှိတာ စစ်ကြည့်ပြီး စတင်ပါ။"</string>
@@ -1192,7 +1194,7 @@
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ငြင်းပယ်ပါ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string>
     <string name="show_ime" msgid="2506087537466597099">"စက်၏ကီးဘုတ်ကိုအသုံးပြုနေစဉ် ၎င်းကိုမျက်နှာပြင်ပေါ်တွင် ထားပါ"</string>
-    <string name="hardware" msgid="194658061510127999">"ကီးဘုတ်အတုပြရန်"</string>
+    <string name="hardware" msgid="194658061510127999">"ပကတိအသွင်ကီးဘုတ်ပြရန်"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ရုပ်ပိုင်းဆိုင်ရာ အသွင်အပြင်ကို ပြင်ဆင်သတ်မှတ်ပါ"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1298,7 +1300,7 @@
     <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
     <string name="back_button_label" msgid="2300470004503343439">"နောက်သို့"</string>
     <string name="next_button_label" msgid="1080555104677992408">"ရှေ့သို့"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"ကျော်"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"ကျော်ရန်"</string>
     <string name="no_matches" msgid="8129421908915840737">"ထပ်တူမတွေ့ရှိပါ"</string>
     <string name="find_on_page" msgid="1946799233822820384">"စာမျက်နှာတွင်ရှာဖွေရန်"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e19a131..be25f67 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -226,7 +226,7 @@
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefoninnstillinger"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Lås skjermen"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"Slå av"</string>
-    <string name="global_action_emergency" msgid="7112311161137421166">"Nødssituasjon"</string>
+    <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituasjon"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Utfør feilrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
@@ -715,7 +715,7 @@
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Trykk på menyknappen for å låse opp eller ringe et nødnummer."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Trykk på menyknappen for å låse opp."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn mønster for å låse opp"</string>
-    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødssituasjon"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituasjon"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbake til samtale"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Riktig!"</string>
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv på nytt"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="email" msgid="4560673117055050403">"E-post"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Kart"</string>
-    <string name="browse" msgid="6079864138582486027">"Bla gjennom"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lite ledig lagringsplass"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Enkelte systemfunksjoner fungerer muligens ikke slik de skal"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Det er ikke nok lagringsplass for systemet. Kontrollér at du har 250 MB ledig plass, og start på nytt."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB for MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trykk for å få flere alternativ."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Lydtilbehøret støttes ikke"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trykk for mer informasjon"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trykk for å slå av feilsøking via USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 82b5c04..747f807 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -252,7 +252,7 @@
     <string name="notification_hidden_text" msgid="1135169301897151909">"लुकेका सामाग्रीहरू"</string>
     <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"नीतिद्वारा लुकाइएका सामग्री"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"भर्चुअल किबोर्ड"</string>
-    <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"भौतिक किबोर्ड"</string>
+    <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"वास्तविक किबोर्ड"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षा"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"कार मोड"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"खाताको स्थिति"</string>
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> पृष्ठभूमिमा चल्दैछ"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> अनुप्रयोगहरू पृष्ठभूमिमा चल्दैछन्"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ब्याट्री र डेटा प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ कार्यहरू"</string>
     <string name="email" msgid="4560673117055050403">"इमेल"</string>
     <string name="dial" msgid="4204975095406423102">"फोन गर्नुहोस्"</string>
-    <string name="map" msgid="5441053548030107189">"नक्सा"</string>
-    <string name="browse" msgid="6079864138582486027">"ब्राउज गर्नुहोस्"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"भण्डारण ठाउँ सकिँदै छ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"सायद केही प्रणाली कार्यक्रमहरूले काम गर्दैनन्"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"प्रणालीको लागि पर्याप्त भण्डारण छैन। तपाईँसँग २५० मेगा बाइट ठाउँ खाली भएको निश्चित गर्नुहोस् र फेरि सुरु गर्नुहोस्।"</string>
@@ -1184,10 +1186,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI को लागि USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"अडियोको सहायक सामग्रीलाई समर्थन छैन"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"थप जानकारीका लागि ट्याप गर्नुहोस्"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB डिबगिङलाई असक्षम गर्न ट्याप गर्नुहोस्।"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङ असक्षम पार्न चयन गर्नुहोस्।"</string>
@@ -1198,7 +1198,7 @@
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"साझेदारी गर्नुहोस्"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"अस्वीकार गर्नुहोस्"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कुञ्जीपाटी परिवर्तन गर्नुहोस्"</string>
-    <string name="show_ime" msgid="2506087537466597099">"भौतिक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string>
+    <string name="show_ime" msgid="2506087537466597099">"वास्तविक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string>
     <string name="hardware" msgid="194658061510127999">"भर्चुअल किबोर्ड देखाउनुहोस्"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"फिजिकल किबोर्डलाई कन्फिगर गर्नुहोस्"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 0d7d8c7..506c195 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo voor de detailhandel"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps uitgevoerd op achtergrond"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> wordt uitgevoerd op de achtergrond"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is op de achtergrond actief"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps worden uitgevoerd op de achtergrond"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik voor informatie over batterij- en datagebruik"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik voor batterij- en datagebruik"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefoon"</string>
-    <string name="map" msgid="5441053548030107189">"Kaart"</string>
-    <string name="browse" msgid="6079864138582486027">"Browsen"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Onvoldoende opslagruimte voor het systeem. Zorg ervoor dat je 250 MB vrije ruimte hebt en start opnieuw."</string>
@@ -1472,7 +1474,7 @@
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Volume verhogen tot boven het aanbevolen niveau?\n\nAls u langere tijd op hoog volume naar muziek luistert, raakt je gehoor mogelijk beschadigd."</string>
     <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Sneltoets voor toegankelijkheid gebruiken?"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Wanneer de sneltoets is ingeschakeld, kun je drie seconden op beide volumeknoppen drukken om een toegankelijkheidsfunctie te starten.\n\n Huidige toegankelijkheidsfunctie:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Je kunt de functie wijzigen in Instellingen &gt; Toegankelijkheid."</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Wanneer de snelkoppeling is ingeschakeld, kun je drie seconden op beide volumeknoppen drukken om een toegankelijkheidsfunctie te starten.\n\n Huidige toegankelijkheidsfunctie:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Je kunt de functie wijzigen in Instellingen &gt; Toegankelijkheid."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Sneltoets uitschakelen"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Sneltoets gebruiken"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ingeschakeld"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 14a6ba1..5066865 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -265,7 +265,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ਕਨੈਕਸ਼ਨ"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਹਨ"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -292,13 +292,13 @@
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"ਸਰੀਰ ਸੰਵੇਦਕ"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"ਆਪਣੇ ਸਰੀਰ ਦੇ ਅਹਿਮ ਚਿੰਨ੍ਹਾਂ ਬਾਰੇ ਸੰਵੇਦਕ ਡੈਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਇੰਟਰੈਕਟ ਕਰ ਰਹੇ ਹੋ।"</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨਾ"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਕਿਸੇ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰਨਾ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ।"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਈ ਟੱਚ ਚਾਲੂ ਕਰਨਾ"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"ਟੈਪ ਕੀਤੀਆਂ ਆਈਟਮਾਂ ਨੂੰ ਉੱਚੀ ਆਵਾਜ਼ ਵਿੱਚ ਬੋਲਿਆ ਜਾਵੇਗਾ ਅਤੇ ਸਕ੍ਰੀਨ ਦੀ ਸੰਕੇਤਾਂ ਦੀ ਵਰਤੋਂ ਨਾਲ ਪੜਚੋਲ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ।"</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ਜੋ ਟੈਕਸਟ ਤੁਸੀਂ ਟਾਈਪ ਕਰਦੇ ਹੋ, ਉਸਦਾ ਨਿਰੀਖਣ ਕਰੋ"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਟਾਈਪ ਕੀਤੀ ਲਿਖਤ ਦਾ ਨਿਰੀਖਣ ਕਰਨਾ"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ਇਸ ਵਿੱਚ ਨਿੱਜੀ ਡੈਟਾ ਸ਼ਾਮਲ ਹੈ ਜਿਵੇਂ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ ਅਤੇ ਪਾਸਵਰਡ।"</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ਡਿਸਪਲੇ ਵੱਡਦਰਸ਼ੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ"</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"ਡਿਸਪਲੇ ਵੱਡਦਰਸ਼ੀਕਰਨ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ਡਿਸਪਲੇ ਦੇ ਜ਼ੂਮ ਪੱਧਰ ਅਤੇ ਸਥਿਤੀ ਨੂੰ ਨਿਯੰਤ੍ਰਿਤ ਕਰੋ।"</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"ਸੰਕੇਤ ਕਰਦੀ ਹੈ"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ਟੈਪ ਕਰ ਸਕਦੀ ਹੈ, ਸਵਾਈਪ ਕਰ ਸਕਦੀ ਹੈ, ਪਿੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਹੋਰ ਸੰਕੇਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -749,12 +749,12 @@
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n  <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਆਪਣਾ Google ਸਾਈਨਇਨ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੌਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੌਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"ਕੀ ਪੈਟਰਨ ਭੁੱਲ ਗਏ?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ਖਾਤਾ ਅਨਲੌਕ"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"ਟੈਕਸਟ ਕਿਰਿਆਵਾਂ"</string>
     <string name="email" msgid="4560673117055050403">"ਈਮੇਲ ਕਰੋ"</string>
     <string name="dial" msgid="4204975095406423102">"ਫ਼ੋਨ ਕਰੋ"</string>
-    <string name="map" msgid="5441053548030107189">"ਨਕਸ਼ਾ ਖੋਲ੍ਹੋ"</string>
-    <string name="browse" msgid="6079864138582486027">"ਬ੍ਰਾਊਜ਼ ਕਰੋ"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ਸਟੋਰੇਜ ਸਪੇਸ ਖ਼ਤਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ਕੁਝ ਸਿਸਟਮ ਫੰਕਸ਼ਨ ਕੰਮ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੇ"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"ਸਿਸਟਮ ਲਈ ਪੂਰੀ ਸਟੋਰੇਜ ਨਹੀਂ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੇ ਕੋਲ 250MB ਖਾਲੀ ਸਪੇਸ ਹੈ ਅਤੇ ਰੀਸਟਾਰਟ ਕਰੋ।"</string>
@@ -1020,9 +1022,9 @@
     <string name="whichImageCaptureApplication" msgid="3680261417470652882">"ਇਸ ਨਾਲ ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"%1$s ਨਾਲ ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"ਚਿਤਰ ਕੈਪਚਰ ਕਰੋ"</string>
-    <string name="alwaysUse" msgid="4583018368000610438">"ਇਸ ਕਿਰਿਆ ਲਈ ਬਾਇ ਡਿਫੌਲਟ ਵਰਤੋ।"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ਇਸ ਕਿਰਿਆ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ।"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"ਇੱਕ ਵੱਖਰਾ ਖਾਤਾ ਵਰਤੋ"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਸ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਡਿਫੌਲਟ ਹਟਾਓ।"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ &gt; ਐਪਸ &gt; ਡਾਊਨਲੋਡ ਕੀਤਿਆਂ ਵਿੱਚ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਹਟਾਓ।"</string>
     <string name="chooseActivity" msgid="7486876147751803333">"ਇੱਕ ਕਿਰਿਆ ਚੁਣੋ"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB ਡੀਵਾਈਸ ਲਈ ਇੱਕ ਐਪ ਚੁਣੋ"</string>
     <string name="noApplications" msgid="2991814273936504689">"ਕੋਈ ਐਪਸ ਇਸ ਕਿਰਿਆ ਨੂੰ ਨਹੀਂ ਕਰ ਸਕਦੇ।"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI ਲਈ USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ਇੱਕ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ਔਡੀਓ ਐਕਸੈਸਰੀ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB ਡੀਬੱਗਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
@@ -1462,12 +1462,12 @@
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ਤੁਸੀਂ ਆਪਣਾ PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
-    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਡਿਫੌਲਟ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਵੱਧ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ ਅਤੇ ਸਾਰਾ ਉਪਭੋਗਤਾ ਡੈਟਾ ਨਸ਼ਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਟੈਬਲੇਟ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਟੈਬਲੇਟ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗੀ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ TV ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ TV ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਫੋਨ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ। ਹੁਣ ਫੋਨ ਫੈਕਟਰੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਤੇ ਰੀਸੈੱਟ ਹੋ ਜਾਏਗਾ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੀ ਟੈਬਲੇਟ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ TV ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਨਲੌਕ ਪੈਟਰਨ ਗ਼ਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫੋਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -1618,7 +1618,7 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"ਬੈਟਰੀ ਸਮਰੱਥਾ ਨੂੰ ਬਿਹਤਰ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਪਿਛੋਕੜ ਡੈਟਾ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਮੈਸੇਜਿੰਗ ਅਤੇ ਹੋਰ ਐਪਸ, ਜੋ ਸਿੰਕਿੰਗ ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਆਟੋਮੈਟਿਕਲੀ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਹੀ ਹੁੰਦੀ ਹੈ।"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"ਬੈਟਰੀ ਲਾਈਫ਼ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਵਿੱਚ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਪਿਛੋਕੜ ਡੈਟੇ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਸੰਦੇਸ਼ਕਰਨ ਅਤੇ ਹੋਰ ਐਪਾਂ, ਜੋ ਸਮਕਾਲੀਕਰਨ \'ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਆਪਣੇ-ਆਪ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਹੀ ਹੁੰਦੀ ਹੈ।"</string>
     <string name="data_saver_description" msgid="6015391409098303235">"ਡੈਟਾ ਉਪਯੋਗ ਘਟਾਉਣ ਵਿੱਚ ਮਦਦ ਲਈ, ਡੈਟਾ ਸੇਵਰ ਕੁਝ ਐਪਾਂ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਡੈਟਾ ਭੇਜਣ ਜਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਤੋਂ ਰੋਕਦਾ ਹੈ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਵਰਤਮਾਨ ਤੌਰ \'ਤੇ ਵਰਤੀ ਜਾ ਰਹੀ ਐਪ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਉਹ ਇੰਝ ਕਦੇ-ਕਦਾਈਂ ਕਰ ਸਕਦੀ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਸ ਦਾ ਮਤਲਬ ਇਹ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਚਿਤਰ ਤਦ ਤੱਕ ਨਹੀਂ ਵਿਖਾਏ ਜਾਂਦੇ, ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ \'ਤੇ ਟੈਪ ਨਹੀਂ ਕਰਦੇ।"</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"ਕੀ ਡੈਟਾ ਸੇਵਰ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"ਚਾਲੂ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ca0464c..8e22ff2 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Przeglądarka"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kończy się miejsce"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektóre funkcje systemu mogą nie działać"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Za mało pamięci w systemie. Upewnij się, że masz 250 MB wolnego miejsca i uruchom urządzenie ponownie."</string>
@@ -1218,10 +1220,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB w trybie MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Kliknij, by wyświetlić więcej opcji."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Nieobsługiwane akcesorium audio"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Kliknij, aby uzyskać więcej informacji"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Kliknij, by wyłączyć debugowanie USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index fc58d2c..975dc07 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefone"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Procurar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não há armazenamento suficiente para o sistema. Certifique-se de ter 250 MB de espaço livre e reinicie."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index d8395bd..1048800 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acções de texto"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Telemóvel"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Procurar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Está quase sem espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema poderão não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não existe armazenamento suficiente para o sistema. Certifique-se de que tem 250 MB de espaço livre e reinicie."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fc58d2c..975dc07 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefone"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Procurar"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não há armazenamento suficiente para o sistema. Certifique-se de ter 250 MB de espaço livre e reinicie."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 0c16186..2d5545b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acțiuni pentru text"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Hartă"</string>
-    <string name="browse" msgid="6079864138582486027">"Răsfoiți"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spațiul de stocare aproape ocupat"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcții de sistem să nu funcționeze"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Spațiu de stocare insuficient pentru sistem. Asigurați-vă că aveți 250 MB de spațiu liber și reporniți."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 7e6a8da..60cf42c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -213,7 +213,7 @@
     <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Подготовка обновлений…"</string>
     <string name="reboot_to_update_package" msgid="3871302324500927291">"Обработка обновлений…"</string>
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Перезагрузка…"</string>
-    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сброс настроек"</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сбросить все данные"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Перезагрузка…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
@@ -272,9 +272,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Деморежим для магазина"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-подключение"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работающие в фоновом режиме"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" работает в фоновом режиме"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> в фоновом режиме"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) работает в фоновом режиме"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Нажмите, чтобы увидеть данные об энергопотреблении и объеме трафика"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
     <string name="email" msgid="4560673117055050403">"Письмо"</string>
     <string name="dial" msgid="4204975095406423102">"Телефон"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Поиск"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Недостаточно памяти"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некоторые функции могут не работать"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостаточно свободного места для системы. Освободите не менее 250 МБ дискового пространства и перезапустите устройство."</string>
@@ -1218,10 +1220,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI через USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Нажмите, чтобы показать дополнительные параметры."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Аудиоустройство не поддерживается"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Нажмите, чтобы получить дополнительную информацию"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Нажмите, чтобы отключить отладку по USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
@@ -1782,7 +1782,7 @@
     <string name="reset_retail_demo_mode_title" msgid="2370249087943803584">"Сбросить настройки устройства?"</string>
     <string name="reset_retail_demo_mode_text" msgid="5481925817590883246">"Нажмите здесь, чтобы сбросить настройки"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Запуск деморежима…"</string>
-    <string name="demo_restarting_message" msgid="952118052531642451">"Сброс настроек…"</string>
+    <string name="demo_restarting_message" msgid="952118052531642451">"Сброс данных…"</string>
     <string name="demo_user_inactivity_timeout_title" msgid="6596109959002331334">"Сбросить настройки устройства?"</string>
     <string name="demo_user_inactivity_timeout_countdown" msgid="5675588824402569506">"Все изменения будут утеряны. Деморежим будет перезапущен через <xliff:g id="TIMEOUT">%1$s</xliff:g> сек."</string>
     <string name="demo_user_inactivity_timeout_left_button" msgid="5314271347014802475">"Отмена"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 33c384e..bdf1d3d 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -986,8 +986,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"පෙළ ක්‍රියාවන්"</string>
     <string name="email" msgid="4560673117055050403">"ඊ-තැපෑල"</string>
     <string name="dial" msgid="4204975095406423102">"දුරකථනය"</string>
-    <string name="map" msgid="5441053548030107189">"සිතියම"</string>
-    <string name="browse" msgid="6079864138582486027">"සොයන්න"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ආචයනය ඉඩ ප්‍රමාණය අඩු වී ඇත"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"සමහර පද්ධති කාර්යයන් ක්‍රියා නොකරනු ඇත"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"පද්ධතිය සඳහා ප්‍රමාණවත් ඉඩ නොමැත. ඔබට 250MB නිදහස් ඉඩක් තිබෙන ඔබට තිබෙන බව සහතික කරගෙන නැවත උත්සාහ කරන්න."</string>
@@ -1180,10 +1182,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI සඳහා USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ශ්‍රව්‍ය ආයිත්තම සහාය නොදක්වයි"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB නිදොස්කරණය අබල කිරීමට තට්ටු කරන්න."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0bc8164..f460244 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
     <string name="email" msgid="4560673117055050403">"E-mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefón"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Prehliadať"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"V úložisku nie je dostatok voľného miesta pre systém. Zaistite, aby ste mali 250 MB voľného miesta a zariadenie reštartujte."</string>
@@ -1066,7 +1068,7 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Zvoľte akciu"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Zvoľte aplikáciu pre zariadenie USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Túto akciu nemôžu vykonávať žiadne aplikácie."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> sa zastavila"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> sa zastavila"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> sa zastavil"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sa opakovane zastavuje"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sa opakovane zastavuje"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 8ac1b4d..7f166ef 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
     <string name="email" msgid="4560673117055050403">"E-pošta"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Zemljevid"</string>
-    <string name="browse" msgid="6079864138582486027">"Brskanje"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nekatere sistemske funkcije morda ne delujejo"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"V shrambi ni dovolj prostora za sistem. Sprostite 250 MB prostora in znova zaženite napravo."</string>
@@ -1218,10 +1220,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Dotaknite se za več možnosti."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Zvočna oprema ni podprta"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Dotaknite se za več informacij"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Dotaknite se za izklop odpravljanja napak prek USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 9f2bae8..4590a90 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacionet që ekzekutohen në sfond"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> po ekzekutohet në sfond"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po ekzekutohen në sfond"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trokit për detaje për baterinë dhe përdorimin e të dhënave"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistemi \"android\""</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Veprimet e tekstit"</string>
     <string name="email" msgid="4560673117055050403">"Dërgo mail"</string>
     <string name="dial" msgid="4204975095406423102">"Telefoni"</string>
-    <string name="map" msgid="5441053548030107189">"Harta"</string>
-    <string name="browse" msgid="6079864138582486027">"Shfleto"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Hapësira ruajtëse po mbaron"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Disa funksione të sistemit mund të mos punojnë"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nuk ka hapësirë të mjaftueshme ruajtjeje për sistemin. Sigurohu që të kesh 250 MB hapësirë të lirë dhe pastaj të rifillosh."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB për MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"U lidh me një ndihmës USB-je"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Trokit për më shumë opsione."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Aksesori i audios nuk mbështetet"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Trokit për më shumë informacion"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Trokit për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index ee2c4c8..f43a527 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -269,9 +269,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Режим демонстрације за малопродајне објекте"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB веза"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Апликације покренуте у позадини"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> је покренута у позадини"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ради у позадини"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) су покренуте у позадини"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Додирните да бисте прегледали детаље о батерији и потрошњи података"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Додирните за детаље о батерији и потрошњи података"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
@@ -1004,8 +1004,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
     <string name="email" msgid="4560673117055050403">"Пошаљи имејл"</string>
     <string name="dial" msgid="4204975095406423102">"Позови"</string>
-    <string name="map" msgid="5441053548030107189">"Мапа"</string>
-    <string name="browse" msgid="6079864138582486027">"Прегледај"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Меморијски простор је на измаку"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Неке системске функције можда не функционишу"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Нема довољно меморијског простора за систем. Уверите се да имате 250 MB слободног простора и поново покрените."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0c13829..aeeabd3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textåtgärder"</string>
     <string name="email" msgid="4560673117055050403">"Skicka e-post"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Karta"</string>
-    <string name="browse" msgid="6079864138582486027">"Bläddra"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lagringsutrymmet börjar ta slut"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Det kan hända att vissa systemfunktioner inte fungerar"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Det finns inte tillräckligt med utrymme för systemet. Kontrollera att du har ett lagringsutrymme på minst 250 MB och starta om."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB för MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ansluten till ett USB-tillbehör"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Tryck för fler alternativ."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ljudtillbehöret stöds inte"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Tryck för mer information"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Tryck om du vill inaktivera USB-felsökning."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 8c563a1..6456a7a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -982,8 +982,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Vitendo vya maandishi"</string>
     <string name="email" msgid="4560673117055050403">"Barua pepe"</string>
     <string name="dial" msgid="4204975095406423102">"Simu"</string>
-    <string name="map" msgid="5441053548030107189">"Ramani"</string>
-    <string name="browse" msgid="6079864138582486027">"Vinjari"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhafadhi inakwisha"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Baadhi ya vipengee vya mfumo huenda visifanye kazi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Hifadhi haitoshi kwa ajili ya mfumo. Hakikisha una MB 250 za nafasi ya hifadhi isiyotumika na uanzishe upya."</string>
@@ -1613,8 +1615,8 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"Imesakinishwa na msimamizi wako"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"Imesasishwa na msimamizi wako"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"Imefutwa na msimamizi wako"</string>
-    <string name="battery_saver_description" msgid="1960431123816253034">"Kusaidia kuboresha muda wa matumizi ya betri, kiokoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotegemea usawazishaji huenda zisisasishwe usipozifungua.\n\nKiokoa betri hujizima kiotomatiki wakati kifaa chako kinachaji."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Ili kusaidia kupunguza matumizi ya data, Kiokoa Data huzuia baadhi ya programu kupokea na kutuma data chini chini. Programu ambayo unatumia sasa inaweza kufikia data, lakini si kila wakati. Kwa mfano, haitaonyesha picha hadi utakapozigonga."</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Ili kuboresha muda wa matumizi ya betri, kiokoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotegemea usawazishaji huenda zisisasishwe usipozifungua.\n\nKiokoa betri hujizima kiotomatiki wakati kifaa chako kinachaji."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Ili kusaidia kupunguza matumizi ya data, Kiokoa Data huzuia baadhi ya programu kupokea na kutuma data chini chini. Programu ambayo unatumia sasa inaweza kufikia data, lakini si kila wakati. Kwa mfano, haitaonyesha picha hadi utakapozifungua."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Ungependa Kuwasha Kiokoa Data?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Washa"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 45da7ef..268ba67 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"விற்பனையாளர் டெமோ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB இணைப்பு"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடு பின்னணியில் இயங்குகிறது"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> பின்னணியில் இயங்குகிறது"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பின்னணியில் இயங்குகின்றன"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் தரவு உபயோகம் குறித்த விவரங்களுக்கு, தட்டவும்"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் தரவு உபயோக விவரங்களைக் காண, தட்டவும்"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android அமைப்பு"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"உரை நடவடிக்கைகள்"</string>
     <string name="email" msgid="4560673117055050403">"மின்னஞ்சல்"</string>
     <string name="dial" msgid="4204975095406423102">"ஃபோன்"</string>
-    <string name="map" msgid="5441053548030107189">"வரைபடம்"</string>
-    <string name="browse" msgid="6079864138582486027">"உலாவு"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"சேமிப்பிடம் குறைகிறது"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"சில அமைப்பு செயல்பாடுகள் வேலை செய்யாமல் போகலாம்"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"முறைமையில் போதுமான சேமிப்பகம் இல்லை. 250மெ.பை. அளவு காலி இடவசதி இருப்பதை உறுதிசெய்து மீண்டும் தொடங்கவும்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 3fbb340..dfd6603 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"వచనానికి సంబంధించిన చర్యలు"</string>
     <string name="email" msgid="4560673117055050403">"ఇమెయిల్"</string>
     <string name="dial" msgid="4204975095406423102">"ఫోన్"</string>
-    <string name="map" msgid="5441053548030107189">"మ్యాప్"</string>
-    <string name="browse" msgid="6079864138582486027">"బ్రౌజ్ చేయండి"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"నిల్వ ఖాళీ అయిపోతోంది"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"కొన్ని సిస్టమ్ కార్యాచరణలు పని చేయకపోవచ్చు"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"సిస్టమ్ కోసం తగినంత నిల్వ లేదు. మీకు 250MB ఖాళీ స్థలం ఉందని నిర్ధారించుకుని, పునఃప్రారంభించండి."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI కోసం USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ఉపకరణానికి కనెక్ట్ చేయబడింది"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ఆడియో ఉపకరణానికి మద్దతు లేదు"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"మరింత సమాచారం కోసం నొక్కండి"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి నొక్కండి."</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 2278ca8..40a239b 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"การทำงานของข้อความ"</string>
     <string name="email" msgid="4560673117055050403">"อีเมล"</string>
     <string name="dial" msgid="4204975095406423102">"โทรศัพท์"</string>
-    <string name="map" msgid="5441053548030107189">"แผนที่"</string>
-    <string name="browse" msgid="6079864138582486027">"เรียกดู"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"พื้นที่จัดเก็บเหลือน้อย"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"บางฟังก์ชันระบบอาจไม่ทำงาน"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"พื้นที่เก็บข้อมูลไม่เพียงพอสำหรับระบบ โปรดตรวจสอบว่าคุณมีพื้นที่ว่าง 250 MB แล้วรีสตาร์ท"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB สำหรับ MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"ไม่รองรับอุปกรณ์เสริมสำหรับเสียง"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"แตะเพื่อปิดใช้การแก้ไขข้อบกพร่องของ USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c4d40d1..54dd049 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
     <string name="email" msgid="4560673117055050403">"Mag-email"</string>
     <string name="dial" msgid="4204975095406423102">"Telepono"</string>
-    <string name="map" msgid="5441053548030107189">"Mapa"</string>
-    <string name="browse" msgid="6079864138582486027">"Mag-browse"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Maaaring hindi gumana nang tama ang ilang paggana ng system"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Walang sapat na storage para sa system. Tiyaking mayroon kang 250MB na libreng espasyo at i-restart."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para sa MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang accessory ng USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"I-tap para sa higit pang mga opsyon."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Hindi sinusuportahan ang audio accessory"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"I-tap para sa higit pang impormasyon"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"I-tap upang i-disable ang pag-debug ng USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c94fbd4..2fda27c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -265,7 +265,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Uyarılar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Mağaza demo"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB bağlantısı"</string>
-    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Uygulamalar arka planda çalışıyor"</string>
+    <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Arka planda çalışan uygulamalar"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> arka planda çalışıyor"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama arka planda çalışıyor"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Metin eylemleri"</string>
     <string name="email" msgid="4560673117055050403">"E-posta"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Harita"</string>
-    <string name="browse" msgid="6079864138582486027">"Göz at"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Depolama alanı bitiyor"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bazı sistem işlevleri çalışmayabilir"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Sistem için yeterli depolama alanı yok. 250 MB boş alanınızın bulunduğundan emin olun ve yeniden başlatın."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"MIDI için USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Diğer seçenekler için dokunun."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Ses aksesuarı desteklenmiyor"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Daha fazla bilgi için dokunun"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ac36114..f1d5d10 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -274,7 +274,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Додатки, які працюють у фоновому режимі"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> працює у фоновому режимі"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Додатки, які працюють у фоновому режимі: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Торкніться, щоб переглянути інформацію про використання заряду акумулятора та даних"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
@@ -1024,8 +1024,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string>
     <string name="email" msgid="4560673117055050403">"Електронна пошта"</string>
     <string name="dial" msgid="4204975095406423102">"Телефонувати"</string>
-    <string name="map" msgid="5441053548030107189">"Карта"</string>
-    <string name="browse" msgid="6079864138582486027">"Переглянути"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Недостатньо місця для системи. Переконайтесь, що на пристрої є 250 Мб вільного місця, і повторіть спробу."</string>
@@ -1066,8 +1068,8 @@
     <string name="chooseActivity" msgid="7486876147751803333">"Виберіть дію"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Вибрати програму для пристрою USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Жодна програма не може виконати цю дію."</string>
-    <string name="aerr_application" msgid="250320989337856518">"Додаток <xliff:g id="APPLICATION">%1$s</xliff:g> перестав працювати"</string>
-    <string name="aerr_process" msgid="6201597323218674729">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> перестав працювати"</string>
+    <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g>: збій у роботі"</string>
+    <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g>: збій у роботі"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"Додаток <xliff:g id="APPLICATION">%1$s</xliff:g> періодично перестає працювати"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"Процес \"<xliff:g id="PROCESS">%1$s</xliff:g>\" періодично перестає працювати"</string>
     <string name="aerr_restart" msgid="7581308074153624475">"Відкрити додаток знову"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4722203..3fcac10 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"متن کی کارروائیاں"</string>
     <string name="email" msgid="4560673117055050403">"ای میل"</string>
     <string name="dial" msgid="4204975095406423102">"فون کریں"</string>
-    <string name="map" msgid="5441053548030107189">"نقشہ"</string>
-    <string name="browse" msgid="6079864138582486027">"براؤز کریں"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"اسٹوریج کی جگہ ختم ہو رہی ہے"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ممکن ہے سسٹم کے کچھ فنکشنز کام نہ کریں"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"‏سسٹم کیلئے کافی اسٹوریج نہیں ہے۔ اس بات کو یقینی بنائیں کہ آپ کے پاس 250MB خالی جگہ ہے اور دوبارہ شروع کریں۔"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"‏MIDI کیلئے USB"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"‏ایک USB لوازم سے مربوط ہے"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"آڈیو لوازم تعاون یافتہ نہیں ہے"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"مزید معلومات کے لیے تھپتھپائيں"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے تھپتھپائیں۔"</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 1fdfc45..3ca3933 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo rejim"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB orqali ulanish"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Fonda ishlayotgan ilovalar"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> fonda ishlamoqda"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> orqa fonda ishlayapti"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova fonda ishlamoqda"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya va trafik sarfiga oid tafsilotlarni olish uchun ustiga bosing"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android tizimi"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Matn yozish"</string>
     <string name="email" msgid="4560673117055050403">"E-pochta"</string>
     <string name="dial" msgid="4204975095406423102">"Telefon"</string>
-    <string name="map" msgid="5441053548030107189">"Xarita"</string>
-    <string name="browse" msgid="6079864138582486027">"Tanlash"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Xotirada bo‘sh joy tugamoqda"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ba‘zi tizim funksiyalari ishlamasligi mumkin"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Tizim uchun xotirada joy yetarli emas. Avval 250 megabayt joy bo‘shatib, keyin qurilmani o‘chirib yoqing."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index c39901f..adb01cb 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -266,9 +266,9 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Giới thiệu bán lẻ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Kết nối USB"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Ứng dụng đang chạy trong nền"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy trong nền"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy ẩn"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang chạy trong nền"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Nhấn để biết chi tiết về pin và mức sử dụng dữ liệu"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tác vụ văn bản"</string>
     <string name="email" msgid="4560673117055050403">"Email"</string>
     <string name="dial" msgid="4204975095406423102">"Điện thoại"</string>
-    <string name="map" msgid="5441053548030107189">"Bản đồ"</string>
-    <string name="browse" msgid="6079864138582486027">"Duyệt qua"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Sắp hết dung lượng lưu trữ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Một số chức năng hệ thống có thể không hoạt động"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Không đủ bộ nhớ cho hệ thống. Đảm bảo bạn có 250 MB dung lượng trống và khởi động lại."</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB cho MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"Nhấn để biết thêm tùy chọn."</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"Phụ kiện âm thanh không được hỗ trợ"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"Nhấn để biết thêm thông tin"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"Nhấn để vô hiệu hóa gỡ lỗi USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 8031be6..e73b852 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="email" msgid="4560673117055050403">"电子邮件"</string>
     <string name="dial" msgid="4204975095406423102">"电话"</string>
-    <string name="map" msgid="5441053548030107189">"地图"</string>
-    <string name="browse" msgid="6079864138582486027">"浏览"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"存储空间不足"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"某些系统功能可能无法正常使用"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系统存储空间不足。请确保您有250MB的可用空间,然后重新启动。"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"正在通过 USB 连接到 MIDI 接口"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到USB配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"点按即可查看更多选项。"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"音频配件不受支持"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"点按即可了解详情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"点按即可停用 USB 调试功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择停用USB调试。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 3dc0cd08..ffa6ebe 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -266,7 +266,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售示範"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"正在背景中執行的應用程式"</string>
-    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> 正在背景中執行"</string>
+    <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在背景執行"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景中執行"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕按即可查看電池和數據用量詳情"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="email" msgid="4560673117055050403">"電郵"</string>
     <string name="dial" msgid="4204975095406423102">"撥打電話"</string>
-    <string name="map" msgid="5441053548030107189">"地圖"</string>
-    <string name="browse" msgid="6079864138582486027">"瀏覽"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系統儲存空間不足。請確認裝置有 250 MB 的可用空間,然後重新啟動。"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕按即可查看更多選項。"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕按即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"輕按即可停用 USB 偵錯功能。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
@@ -1198,7 +1198,7 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕按即可選取語言和鍵盤配置"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"「<xliff:g id="NAME">%s</xliff:g>」目前在其他應用程式上顯示內容"</string>
+    <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"「<xliff:g id="NAME">%s</xliff:g>」目前可顯示在其他應用程式上面"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
     <string name="alert_windows_notification_message" msgid="8917232109522912560">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string>
     <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"關閉"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2916c42..dca2cca 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -268,7 +268,7 @@
     <string name="notification_channel_foreground_service" msgid="6665375982962336520">"在背景執行的應用程式"</string>
     <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在背景執行"</string>
     <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景執行"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕觸即可取得電池和數據用量的詳細資料"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕觸即可查看電池和數據用量詳情"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
     <string name="email" msgid="4560673117055050403">"電子郵件"</string>
     <string name="dial" msgid="4204975095406423102">"電話"</string>
-    <string name="map" msgid="5441053548030107189">"地圖"</string>
-    <string name="browse" msgid="6079864138582486027">"瀏覽"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"系統儲存空間不足。請確定你已釋出 250MB 的可用空間,然後重新啟動。"</string>
@@ -1178,10 +1180,8 @@
     <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接 USB 配件"</string>
     <string name="usb_notification_message" msgid="3370903770828407960">"輕觸即可查看更多選項。"</string>
-    <!-- no translation found for usb_unsupported_audio_accessory_title (2256529893240208458) -->
-    <skip />
-    <!-- no translation found for usb_unsupported_audio_accessory_message (7811865061127547035) -->
-    <skip />
+    <string name="usb_unsupported_audio_accessory_title" msgid="2256529893240208458">"不支援的音訊配件"</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="7811865061127547035">"輕觸即可瞭解詳情"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="4948470599328424059">"輕觸即可停用 USB 偵錯。"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 9da0d4f..1979246 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -984,8 +984,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
     <string name="email" msgid="4560673117055050403">"I-imeyili"</string>
     <string name="dial" msgid="4204975095406423102">"Ifoni"</string>
-    <string name="map" msgid="5441053548030107189">"Imephu"</string>
-    <string name="browse" msgid="6079864138582486027">"Dlulisa amehlo"</string>
+    <!-- no translation found for map (6068210738233985748) -->
+    <skip />
+    <!-- no translation found for browse (6993590095938149861) -->
+    <skip />
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Isikhala sokulondoloza siyaphela"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Eminye imisebenzi yohlelo ingahle ingasebenzi"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Akusona isitoreji esanele sesistimu. Qiniseka ukuthi unesikhala esikhululekile esingu-250MB uphinde uqalise kabusha."</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 12fa8fc..5abc47d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -425,9 +425,6 @@
     <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
     <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
 
-    <!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled -->
-    <bool translatable="false" name="config_wifi_hotspot2_enabled">false</bool>
-
     <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
     <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
 
@@ -2933,4 +2930,7 @@
     <!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
     <bool name="config_handleVolumeKeysInWindowManager">false</bool>
 
+    <!-- Volume level of in-call notification tone playback,
+         relative to the overall voice call stream volume [0..100] -->
+    <integer name="config_inCallNotificationVolumeRelative">67</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 134527c..8fc57b1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4489,7 +4489,7 @@
         <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
     </plurals>
 
-    <string name="default_notification_channel_label">Miscellaneous</string>
+    <string name="default_notification_channel_label">Uncategorized</string>
 
     <string name="importance_from_user">You set the importance of these notifications.</string>
     <string name="importance_from_person">This is important because of the people involved.</string>
@@ -4634,6 +4634,15 @@
     <!-- Toast message shown when user manually request autofill but service could not figure out the data that would autofill the screen contents. [CHAR LIMIT=NONE] -->
     <string name="autofill_error_cannot_autofill">Contents can\u2019t be autofilled</string>
 
+    <!-- Accessibility string to announce there are no autofill suggestions in the autofill picker. [CHAR LIMIT=NONE] -->
+    <string name="autofill_picker_no_suggestions">No autofill suggestions</string>
+
+    <!-- Accessibility string to announce there are some autofill suggestions in the autofill picker. [CHAR LIMIT=NONE] -->
+    <plurals name="autofill_picker_some_suggestions">
+        <item quantity="one">One autofill suggestion</item>
+        <item quantity="other"><xliff:g id="count" example="Two">%1$s</xliff:g> autofill suggestions</item>
+    </plurals>
+
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
     <string name="autofill_save_title">Save to &lt;b><xliff:g id="label" example="MyPass">%1$s</xliff:g>&lt;/b>?</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8ff7f67..c688414 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1777,7 +1777,6 @@
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
   <java-symbol type="bool" name="config_wifi_background_scan_support" />
   <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="bool" name="config_wifi_hotspot2_enabled" />
   <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
@@ -2908,6 +2907,8 @@
   <java-symbol type="id" name="autofill_save_yes" />
   <java-symbol type="id" name="autofill_save_close" />
   <java-symbol type="string" name="autofill_error_cannot_autofill" />
+  <java-symbol type="string" name="autofill_picker_no_suggestions" />
+  <java-symbol type="plurals" name="autofill_picker_some_suggestions" />
   <java-symbol type="string" name="autofill" />
   <java-symbol type="string" name="autofill_picker_accessibility_title " />
   <java-symbol type="string" name="autofill_save_accessibility_title " />
@@ -3029,4 +3030,6 @@
   <java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
 
   <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
+
+  <java-symbol type="integer" name="config_inCallNotificationVolumeRelative" />
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 94a515b..63adeb7 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1172,6 +1172,7 @@
         </activity>
         <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
         <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
+        <activity android:name="com.android.internal.app.IntentForwarderActivityTest$IntentForwarderWrapperActivity"/>
 
         <receiver android:name="android.app.activity.AbortReceiver">
             <intent-filter android:priority="1">
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
index 5e426e8..9c904d1 100644
--- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -68,19 +68,19 @@
         assertEquals(4, fileEntries.length);
         FontFileResourceEntry font1 = fileEntries[0];
         assertEquals(400, font1.getWeight());
-        assertEquals(false, font1.isItalic());
+        assertEquals(0, font1.getItalic());
         assertEquals("res/font/samplefont.ttf", font1.getFileName());
         FontFileResourceEntry font2 = fileEntries[1];
         assertEquals(400, font2.getWeight());
-        assertEquals(true, font2.isItalic());
+        assertEquals(1, font2.getItalic());
         assertEquals("res/font/samplefont2.ttf", font2.getFileName());
         FontFileResourceEntry font3 = fileEntries[2];
         assertEquals(800, font3.getWeight());
-        assertEquals(false, font3.isItalic());
+        assertEquals(0, font3.getItalic());
         assertEquals("res/font/samplefont3.ttf", font3.getFileName());
         FontFileResourceEntry font4 = fileEntries[3];
         assertEquals(800, font4.getWeight());
-        assertEquals(true, font4.isItalic());
+        assertEquals(1, font4.getItalic());
         assertEquals("res/font/samplefont4.ttf", font4.getFileName());
     }
 
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index 6e41831..8b5cc60 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -16,10 +16,13 @@
 
 package android.text.method;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.InputType;
+import android.util.KeyUtils;
 import android.view.KeyEvent;
+import android.widget.EditText;
 import android.widget.TextView.BufferType;
 import org.junit.Before;
 import org.junit.Test;
@@ -33,13 +36,21 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class BackspaceTest extends KeyListenerTestCase {
+public class BackspaceTest {
+    private EditText mTextView;
+
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
         public int getInputType() {
             return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
         }
     };
 
+    @Before
+    public void setup() {
+        mTextView = new EditText(InstrumentationRegistry.getInstrumentation().getContext());
+    }
+
+
     // Sync the state to the TextView and call onKeyDown with KEYCODE_DEL key event.
     // Then update the state to the result of TextView.
     private void backspace(final EditorState state, int modifiers) {
@@ -47,7 +58,8 @@
         mTextView.setKeyListener(mKeyListener);
         mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
 
-        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_DEL, modifiers);
+        final KeyEvent keyEvent = KeyUtils.generateKeyEvent(
+            KeyEvent.KEYCODE_DEL, KeyEvent.ACTION_DOWN, modifiers);
         mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
 
         state.mText = mTextView.getText();
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index 6914e21..c3a5f80 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -16,10 +16,13 @@
 
 package android.text.method;
 
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.InputType;
+import android.util.KeyUtils;
 import android.view.KeyEvent;
+import android.widget.EditText;
 import android.widget.TextView.BufferType;
 
 import org.junit.Before;
@@ -34,13 +37,20 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class ForwardDeleteTest extends KeyListenerTestCase {
+public class ForwardDeleteTest {
+    private EditText mTextView;
+
     private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
         public int getInputType() {
             return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
         }
     };
 
+    @Before
+    public void setup() {
+        mTextView = new EditText(InstrumentationRegistry.getInstrumentation().getContext());
+    }
+
     // Sync the state to the TextView and call onKeyDown with KEYCODE_FORWARD_DEL key event.
     // Then update the state to the result of TextView.
     private void forwardDelete(final EditorState state, int modifiers) {
@@ -48,7 +58,8 @@
         mTextView.setKeyListener(mKeyListener);
         mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
 
-        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL, modifiers);
+        final KeyEvent keyEvent = KeyUtils.generateKeyEvent(
+            KeyEvent.KEYCODE_FORWARD_DEL, KeyEvent.ACTION_DOWN, modifiers);
         mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
 
         state.mText = mTextView.getText();
diff --git a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
deleted file mode 100644
index 99a0091..0000000
--- a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text.method;
-
-import android.app.Instrumentation;
-import android.support.test.InstrumentationRegistry;
-import android.view.KeyEvent;
-import android.widget.EditText;
-
-public abstract class KeyListenerTestCase {
-    protected Instrumentation mInstrumentation;
-    protected EditText mTextView;
-
-    public KeyListenerTestCase() {
-    }
-
-    protected void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mTextView = new EditText(mInstrumentation.getContext());
-    }
-
-    protected static KeyEvent getKey(int keycode, int metaState) {
-        long currentTime = System.currentTimeMillis();
-        return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode,
-                0 /* repeat */, metaState);
-    }
-}
diff --git a/core/tests/coretests/src/android/util/KeyUtils.java b/core/tests/coretests/src/android/util/KeyUtils.java
index b58fda3..593f727 100644
--- a/core/tests/coretests/src/android/util/KeyUtils.java
+++ b/core/tests/coretests/src/android/util/KeyUtils.java
@@ -85,4 +85,19 @@
         }
         inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
     }
+
+    /**
+     * Generates a {@link KeyEvent}.
+     *
+     * @param keycode The integer keycode for the event to be generated.
+     * @param keyEventAction The integer {@link KeyEvent} action code.
+     * @param metaState Flags indicating which meta keys are currently pressed.
+     *
+     * @return a new {@link KeyEvent} for current time.
+     */
+    public static KeyEvent generateKeyEvent(int keycode, int keyEventAction, int metaState) {
+        long currentTime = System.currentTimeMillis();
+        return new KeyEvent(currentTime, currentTime, keyEventAction, keycode,
+            0 /* repeat */, metaState);
+    }
 }
diff --git a/core/tests/coretests/src/android/view/DisabledTest.java b/core/tests/coretests/src/android/view/DisabledTest.java
index 992c277..d78e5e9 100644
--- a/core/tests/coretests/src/android/view/DisabledTest.java
+++ b/core/tests/coretests/src/android/view/DisabledTest.java
@@ -16,15 +16,15 @@
 
 package android.view;
 
-import com.android.frameworks.coretests.R;
-import android.test.TouchUtils;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.LargeTest;
-
 import android.test.ActivityInstrumentationTestCase;
-import android.widget.Button;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.KeyEvent;
 import android.view.View;
+import android.widget.Button;
+
+import com.android.frameworks.coretests.R;
 
 /**
  * Exercises {@link android.view.View}'s disabled property.
@@ -45,18 +45,23 @@
 
         final Disabled a = getActivity();
         mDisabled = (Button) a.findViewById(R.id.disabledButton);
-        mDisabled.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                mClicked = true;
-            }
-        });
-
         mDisabledParent = a.findViewById(R.id.clickableParent);
-        mDisabledParent.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                mParentClicked = true;
-            }
-        });
+        getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        mDisabled.setOnClickListener(new View.OnClickListener() {
+                            public void onClick(View v) {
+                                mClicked = true;
+                            }
+                        });
+                        mDisabledParent.setOnClickListener(new View.OnClickListener() {
+                            public void onClick(View v) {
+                                mParentClicked = true;
+                            }
+                        });
+                    }
+                });
     }
 
     @Override
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 742fd60..7b7031b 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -40,6 +40,7 @@
 public class TextClassificationManagerTest {
 
     private static final LocaleList LOCALES = LocaleList.forLanguageTags("en");
+    private static final String NO_TYPE = null;
 
     private TextClassificationManager mTcm;
     private TextClassifier mClassifier;
@@ -102,6 +103,19 @@
     }
 
     @Test
+    public void testSmartSelection_withEmoji() {
+        if (isTextClassifierDisabled()) return;
+
+        String text = "\uD83D\uDE02 Hello.";
+        String selected = "Hello";
+        int startIndex = text.indexOf(selected);
+        int endIndex = startIndex + selected.length();
+
+        assertThat(mClassifier.suggestSelection(text, startIndex, endIndex, LOCALES),
+                isTextSelection(startIndex, endIndex, NO_TYPE));
+    }
+
+    @Test
     public void testClassifyText() {
         if (isTextClassifierDisabled()) return;
 
@@ -172,12 +186,17 @@
                     TextSelection selection = (TextSelection) o;
                     return startIndex == selection.getSelectionStartIndex()
                             && endIndex == selection.getSelectionEndIndex()
-                            && selection.getEntityCount() > 0
-                            && type.equals(selection.getEntity(0));
+                            && typeMatches(selection, type);
                 }
                 return false;
             }
 
+            private boolean typeMatches(TextSelection selection, String type) {
+                return type == null
+                        || (selection.getEntityCount() > 0
+                                && type.trim().equalsIgnoreCase(selection.getEntity(0)));
+            }
+
             @Override
             public void describeTo(Description description) {
                 description.appendValue(
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
new file mode 100644
index 0000000..b18fa74
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(AndroidJUnit4.class)
+public class IntentForwarderActivityTest {
+    private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME =
+            new ComponentName(
+                    "android",
+                    IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE
+            );
+    private static final String TYPE_PLAIN_TEXT = "text/plain";
+
+    private static UserInfo MANAGED_PROFILE_INFO = new UserInfo();
+    static {
+        MANAGED_PROFILE_INFO.id = 10;
+        MANAGED_PROFILE_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE;
+    }
+
+    private static UserInfo CURRENT_USER_INFO = new UserInfo();
+    static {
+        CURRENT_USER_INFO.id = UserHandle.myUserId();
+        CURRENT_USER_INFO.flags = 0;
+    }
+
+    private static IntentForwarderActivity.Injector sInjector;
+    private static ComponentName sComponentName;
+
+    @Mock private IPackageManager mIPm;
+    @Mock private PackageManager mPm;
+    @Mock private UserManager mUserManager;
+
+    @Rule
+    public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule =
+            new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false);
+
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = InstrumentationRegistry.getTargetContext();
+        sInjector = new TestInjector();
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        intent.setType(TYPE_PLAIN_TEXT);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_SEND, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_cannotForward_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent cannot be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(false);
+
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_noManagedProfile_sendIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), anyString(), anyInt(), anyInt())).thenReturn(true);
+
+        // Managed profile does not exist.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create ACTION_SEND intent.
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_SEND);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        assertNull(activity.mStartActivityIntent);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_chooserIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create chooser Intent
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class);
+        intent.setAction(Intent.ACTION_CHOOSER);
+        Intent sendIntent = new Intent(Intent.ACTION_SEND);
+        sendIntent.setComponent(new ComponentName("xx", "yyy"));
+        sendIntent.setType(TYPE_PLAIN_TEXT);
+        intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+
+        Intent innerIntent = activity.mStartActivityIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+        assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+    @Test
+    public void forwardToManagedProfile_canForward_selectorIntent() throws Exception {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+                any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+
+        // Manage profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+
+        // Create selector intent.
+        Intent intent = Intent.makeMainSelectorActivity(
+                Intent.ACTION_VIEW, Intent.CATEGORY_BROWSABLE);
+        IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent);
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mIPm).canForwardTo(
+                intentCaptor.capture(), nullable(String.class), anyInt(), anyInt());
+        assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction());
+
+        assertNotNull(activity.mStartActivityIntent);
+        assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction());
+        assertNull(activity.mStartActivityIntent.getPackage());
+        assertNull(activity.mStartActivityIntent.getComponent());
+        assertEquals(CURRENT_USER_INFO.id, activity.mStartActivityIntent.getContentUserHint());
+
+        Intent innerIntent = activity.mStartActivityIntent.getSelector();
+        assertNotNull(innerIntent);
+        assertEquals(Intent.ACTION_VIEW, innerIntent.getAction());
+        assertNull(innerIntent.getComponent());
+        assertNull(innerIntent.getPackage());
+
+        assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
+    }
+
+
+    public static class IntentForwarderWrapperActivity extends IntentForwarderActivity {
+        private Intent mStartActivityIntent;
+        private int mUserIdActivityLaunchedIn;
+
+        @Override
+        public void onCreate(@Nullable Bundle savedInstanceState) {
+            getIntent().setComponent(sComponentName);
+            super.onCreate(savedInstanceState);
+        }
+
+        @Override
+        protected Injector createInjector() {
+            return sInjector;
+        }
+
+        @Override
+        public void startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean
+                ignoreTargetSecurity, int userId) {
+            mStartActivityIntent = intent;
+            mUserIdActivityLaunchedIn = userId;
+        }
+    }
+
+    class TestInjector implements IntentForwarderActivity.Injector {
+
+        @Override
+        public IPackageManager getIPackageManager() {
+            return mIPm;
+        }
+
+        @Override
+        public UserManager getUserManager() {
+            return mUserManager;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPm;
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
new file mode 100644
index 0000000..1dced75
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.internal.os;
+
+import static android.os.BatteryStats.STATS_SINCE_CHARGED;
+
+import android.os.WorkSource;
+import android.support.test.filters.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Test various BatteryStatsImpl noteStart methods.
+ */
+public class BatteryStatsNoteTest extends TestCase{
+    private static final int UID = 10500;
+    private static final WorkSource WS = new WorkSource(UID);
+
+    /** Test that BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */
+    @SmallTest
+    public void testNoteBluetoothScanResultLocked() throws Exception {
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
+        bi.updateTimeBasesLocked(true, true, 0, 0);
+
+        bi.noteBluetoothScanResultFromSourceLocked(WS);
+        bi.noteBluetoothScanResultFromSourceLocked(WS);
+        assertEquals(2,
+                bi.getUidStats().get(UID).getBluetoothScanResultCounter()
+                        .getCountLocked(STATS_SINCE_CHARGED));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 57d6934..3a16fcf 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -15,6 +15,7 @@
         BatteryStatsUidTest.class,
         BatteryStatsSensorTest.class,
         BatteryStatsBackgroundStatsTest.class,
+        BatteryStatsNoteTest.class,
     })
 public class BatteryStatsTests {
 }
diff --git a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/Android.mk b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/Android.mk
index c70c1d3..5a545e5 100644
--- a/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalLocAllPermsTestApp/Android.mk
@@ -22,6 +22,8 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_STATIC_JAVA_LIBRARIES := junit
+
 LOCAL_PACKAGE_NAME := ExternalLocAllPermsTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
index 7946e1a..b35cbae 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_PACKAGE_NAME := ExternalSharedPermsTestApp
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
index 657d0a40..06812b5 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_PACKAGE_NAME := ExternalSharedPermsBTTestApp
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
index d4450dc..48bceaf 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_PACKAGE_NAME := ExternalSharedPermsDiffKeyTestApp
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
index 8154862..569d102 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+
 LOCAL_SDK_VERSION := current
 
 LOCAL_PACKAGE_NAME := ExternalSharedPermsFLTestApp
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index abdab39..8a36120 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -23,6 +23,7 @@
 import android.annotation.Size;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.StrictMode;
 import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -600,6 +601,13 @@
         src.position(position);
     }
 
+    private void noteHardwareBitmapSlowCall() {
+        if (getConfig() == Config.HARDWARE) {
+            StrictMode.noteSlowCall("Warning: attempt to read pixels from hardware "
+                    + "bitmap, which is very slow operation");
+        }
+    }
+
     /**
      * Tries to make a new bitmap based on the dimensions of this bitmap,
      * setting the new bitmap's config to the one specified, and then copying
@@ -618,6 +626,7 @@
         if (config == Config.HARDWARE && isMutable) {
             throw new IllegalArgumentException("Hardware bitmaps are always immutable");
         }
+        noteHardwareBitmapSlowCall();
         Bitmap b = nativeCopy(mNativePtr, config.nativeInt, isMutable);
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
@@ -635,6 +644,7 @@
      */
     public Bitmap createAshmemBitmap() {
         checkRecycled("Can't copy a recycled bitmap");
+        noteHardwareBitmapSlowCall();
         Bitmap b = nativeCopyAshmem(mNativePtr);
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
@@ -652,6 +662,7 @@
      */
     public Bitmap createAshmemBitmap(Config config) {
         checkRecycled("Can't copy a recycled bitmap");
+        noteHardwareBitmapSlowCall();
         Bitmap b = nativeCopyAshmemConfig(mNativePtr, config.nativeInt);
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
@@ -772,6 +783,7 @@
 
         boolean isHardware = source.getConfig() == Config.HARDWARE;
         if (isHardware) {
+            source.noteHardwareBitmapSlowCall();
             source = nativeCopyPreserveInternalConfig(source.mNativePtr);
         }
 
@@ -1218,6 +1230,7 @@
         if (quality < 0 || quality > 100) {
             throw new IllegalArgumentException("quality must be 0..100");
         }
+        StrictMode.noteSlowCall("Compression of a bitmap is slow");
         Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
         boolean result = nativeCompress(mNativePtr, format.nativeInt,
                 quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
@@ -1792,6 +1805,7 @@
      */
     public void writeToParcel(Parcel p, int flags) {
         checkRecycled("Can't parcel a recycled bitmap");
+        noteHardwareBitmapSlowCall();
         if (!nativeWriteToParcel(mNativePtr, mIsMutable, mDensity, p)) {
             throw new RuntimeException("native writeToParcel failed");
         }
@@ -1838,6 +1852,7 @@
     public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
         checkRecycled("Can't extractAlpha on a recycled bitmap");
         long nativePaint = paint != null ? paint.getNativeInstance() : 0;
+        noteHardwareBitmapSlowCall();
         Bitmap bm = nativeExtractAlpha(mNativePtr, nativePaint, offsetXY);
         if (bm == null) {
             throw new RuntimeException("Failed to extractAlpha on Bitmap");
@@ -1853,6 +1868,8 @@
      */
     public boolean sameAs(Bitmap other) {
         checkRecycled("Can't call sameAs on a recycled bitmap!");
+        noteHardwareBitmapSlowCall();
+        other.noteHardwareBitmapSlowCall();
         if (this == other) return true;
         if (other == null) return false;
         if (other.isRecycled()) {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index f38d8d2..5a56f53 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -123,7 +123,7 @@
     public static final int BOLD_ITALIC = 3;
 
     private int mStyle = 0;
-    private int mBaseWeight = 0;
+    private int mWeight = 0;
 
     // Value for weight and italic. Indicates the value is resolved by font metadata.
     // Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
@@ -233,8 +233,7 @@
                 // TODO: Add ttc and variation font support. (b/37853920)
                 if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
                         0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
-                        fontFile.getWeight(), fontFile.isItalic() ? STYLE_ITALIC : STYLE_NORMAL,
-                        null /* axes */)) {
+                        fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
                     return null;
                 }
             }
@@ -545,7 +544,7 @@
                 return base;
             }
 
-            final int weight = (mWeight == RESOLVE_BY_FONT_TABLE) ? base.mBaseWeight : mWeight;
+            final int weight = (mWeight == RESOLVE_BY_FONT_TABLE) ? base.mWeight : mWeight;
             final boolean italic =
                     (mItalic == RESOLVE_BY_FONT_TABLE) ? (base.mStyle & ITALIC) != 0 : mItalic == 1;
             final int key = weight << 1 | (italic ? 1 : 0);
@@ -883,7 +882,7 @@
 
         native_instance = ni;
         mStyle = nativeGetStyle(ni);
-        mBaseWeight = nativeGetBaseWeight(ni);
+        mWeight = nativeGetWeight(ni);
     }
 
     private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
@@ -1069,7 +1068,7 @@
     private static native long nativeCreateWeightAlias(long native_instance, int weight);
     private static native void nativeUnref(long native_instance);
     private static native int  nativeGetStyle(long native_instance);
-    private static native int  nativeGetBaseWeight(long native_instance);
+    private static native int  nativeGetWeight(long native_instance);
     private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic);
     private static native void nativeSetDefault(long native_instance);
     private static native int[] nativeGetSupportedAxes(long native_instance);
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index bc40191..443aa49 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -188,19 +188,19 @@
 
         // Inset attribute may be overridden by more specific attributes.
         if (a.hasValue(R.styleable.InsetDrawable_inset)) {
-            final InsetValue inset = getInset(a, R.styleable.InsetDrawable_inset, 0);
+            final InsetValue inset = getInset(a, R.styleable.InsetDrawable_inset, new InsetValue());
             state.mInsetLeft = inset;
             state.mInsetTop = inset;
             state.mInsetRight = inset;
             state.mInsetBottom = inset;
         }
-        state.mInsetLeft = getInset(a, R.styleable.InsetDrawable_insetLeft, 0);
-        state.mInsetTop = getInset(a, R.styleable.InsetDrawable_insetTop, 0);
-        state.mInsetRight = getInset(a, R.styleable.InsetDrawable_insetRight, 0);
-        state.mInsetBottom = getInset(a, R.styleable.InsetDrawable_insetBottom, 0);
+        state.mInsetLeft = getInset(a, R.styleable.InsetDrawable_insetLeft, state.mInsetLeft);
+        state.mInsetTop = getInset(a, R.styleable.InsetDrawable_insetTop, state.mInsetTop);
+        state.mInsetRight = getInset(a, R.styleable.InsetDrawable_insetRight, state.mInsetRight);
+        state.mInsetBottom = getInset(a, R.styleable.InsetDrawable_insetBottom, state.mInsetBottom);
     }
 
-    private InsetValue getInset(@NonNull TypedArray a, int index, int defaultValue) {
+    private InsetValue getInset(@NonNull TypedArray a, int index, InsetValue defaultValue) {
         if (a.hasValue(index)) {
             TypedValue tv = a.peekValue(index);
             if (tv.type == TypedValue.TYPE_FRACTION) {
@@ -210,10 +210,13 @@
                 }
                 return new InsetValue(f, 0);
             } else {
-                return new InsetValue(0f, a.getDimensionPixelOffset(index, defaultValue));
+                int dimension = a.getDimensionPixelOffset(index, 0);
+                if (dimension != 0) {
+                    return new InsetValue(0, dimension);
+                }
             }
         }
-        return new InsetValue();
+        return defaultValue;
     }
 
     private void getInsets(Rect out) {
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 41e5af1..c3ef450 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -483,10 +483,10 @@
         final int sourceDensity = mVectorState.mDensity;
         final int targetDensity = mTargetDensity;
         if (targetDensity != sourceDensity) {
-            mDpiScaledWidth = Drawable.scaleFromDensity(
-                    (int) mVectorState.mBaseWidth, sourceDensity, targetDensity, true);
-            mDpiScaledHeight = Drawable.scaleFromDensity(
-                    (int) mVectorState.mBaseHeight,sourceDensity, targetDensity, true);
+            mDpiScaledWidth = Drawable.scaleFromDensity(mVectorState.mBaseWidth, sourceDensity,
+                    targetDensity, true);
+            mDpiScaledHeight = Drawable.scaleFromDensity(mVectorState.mBaseHeight,sourceDensity,
+                    targetDensity, true);
             final int left = Drawable.scaleFromDensity(
                     opticalInsets.left, sourceDensity, targetDensity, false);
             final int right = Drawable.scaleFromDensity(
@@ -497,8 +497,8 @@
                     opticalInsets.bottom, sourceDensity, targetDensity, false);
             mDpiScaledInsets = Insets.of(left, top, right, bottom);
         } else {
-            mDpiScaledWidth = (int) mVectorState.mBaseWidth;
-            mDpiScaledHeight = (int) mVectorState.mBaseHeight;
+            mDpiScaledWidth = mVectorState.mBaseWidth;
+            mDpiScaledHeight = mVectorState.mBaseHeight;
             mDpiScaledInsets = opticalInsets;
         }
 
@@ -675,9 +675,9 @@
                     "<vector> tag requires viewportHeight > 0");
         }
 
-        state.mBaseWidth = a.getDimension(
+        state.mBaseWidth = a.getDimensionPixelSize(
                 R.styleable.VectorDrawable_width, state.mBaseWidth);
-        state.mBaseHeight = a.getDimension(
+        state.mBaseHeight = a.getDimensionPixelSize(
                 R.styleable.VectorDrawable_height, state.mBaseHeight);
 
         if (state.mBaseWidth <= 0) {
@@ -819,8 +819,8 @@
         Mode mTintMode = DEFAULT_TINT_MODE;
         boolean mAutoMirrored;
 
-        float mBaseWidth = 0;
-        float mBaseHeight = 0;
+        int mBaseWidth = 0;
+        int mBaseHeight = 0;
         float mViewportWidth = 0;
         float mViewportHeight = 0;
         Insets mOpticalInsets = Insets.NONE;
@@ -1004,8 +1004,9 @@
         }
 
         private void applyDensityScaling(int sourceDensity, int targetDensity) {
-            mBaseWidth = Drawable.scaleFromDensity(mBaseWidth, sourceDensity, targetDensity);
-            mBaseHeight = Drawable.scaleFromDensity(mBaseHeight, sourceDensity, targetDensity);
+            mBaseWidth = Drawable.scaleFromDensity(mBaseWidth, sourceDensity, targetDensity, true);
+            mBaseHeight = Drawable.scaleFromDensity(mBaseHeight, sourceDensity, targetDensity,
+                    true);
 
             final int insetLeft = Drawable.scaleFromDensity(
                     mOpticalInsets.left, sourceDensity, targetDensity, false);
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index ea804d0..3fe730f 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -599,9 +599,9 @@
         private final Context context;
         private final ServiceConnection serviceConnection;
         private final IKeyChainService service;
-        private KeyChainConnection(Context context,
-                                   ServiceConnection serviceConnection,
-                                   IKeyChainService service) {
+        protected KeyChainConnection(Context context,
+                                     ServiceConnection serviceConnection,
+                                     IKeyChainService service) {
             this.context = context;
             this.serviceConnection = serviceConnection;
             this.service = service;
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
deleted file mode 100644
index a740b13..0000000
--- a/keystore/tests/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-LOCAL_CERTIFICATE := platform
-
-LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := KeyStoreTests
-
-include $(BUILD_PACKAGE)
diff --git a/keystore/tests/AndroidManifest.xml b/keystore/tests/AndroidManifest.xml
deleted file mode 100644
index 415442f..0000000
--- a/keystore/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.security.tests"
-          android:sharedUserId="android.uid.system">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="android.security.tests"
-        android:label="KeyStore Tests">
-    </instrumentation>
-</manifest>
diff --git a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
deleted file mode 100644
index bc8dd13e..0000000
--- a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import android.test.AndroidTestCase;
-
-import java.math.BigInteger;
-import java.util.Date;
-
-import javax.security.auth.x500.X500Principal;
-
-public class KeyPairGeneratorSpecTest extends AndroidTestCase {
-    private static final String TEST_ALIAS_1 = "test1";
-
-    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
-
-    private static final long NOW_MILLIS = System.currentTimeMillis();
-
-    private static final BigInteger SERIAL_1 = BigInteger.ONE;
-
-    /* We have to round this off because X509v3 doesn't store milliseconds. */
-    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
-
-    @SuppressWarnings("deprecation")
-    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
-
-    public void testConstructor_Success() throws Exception {
-        KeyPairGeneratorSpec spec =
-                new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1,
-                        SERIAL_1, NOW, NOW_PLUS_10_YEARS, 0);
-
-        assertEquals("Context should be the one specified", getContext(), spec.getContext());
-
-        assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
-
-        assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
-
-        assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
-
-        assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
-
-        assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
-
-        assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
-    }
-
-    public void testBuilder_Success() throws Exception {
-        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("RSA")
-                .setKeySize(1024)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .setEncryptionRequired()
-                .build();
-
-        assertEquals("Context should be the one specified", getContext(), spec.getContext());
-
-        assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
-
-        assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
-
-        assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
-
-        assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
-
-        assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
-
-        assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
-
-        assertEquals("encryption flag should be on", KeyStore.FLAG_ENCRYPTED, spec.getFlags());
-    }
-
-    public void testConstructor_NullContext_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(null, TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when context is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_NullKeystoreAlias_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), null, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when keystoreAlias is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_NullSubjectDN_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when subjectDN is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_NullSerial_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when startDate is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_NullStartDate_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    null, NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when startDate is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_NullEndDate_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    NOW, null, 0);
-            fail("Should throw IllegalArgumentException when keystoreAlias is null");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testConstructor_EndBeforeStart_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    NOW_PLUS_10_YEARS, NOW, 0);
-            fail("Should throw IllegalArgumentException when end is before start");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
deleted file mode 100644
index 319cf32..0000000
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ /dev/null
@@ -1,974 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import android.app.Activity;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Process;
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeyCharacteristics;
-import android.security.keymaster.KeymasterArguments;
-import android.security.keymaster.KeymasterBlob;
-import android.security.keymaster.KeymasterDefs;
-import android.security.keymaster.OperationResult;
-import android.test.ActivityUnitTestCase;
-import android.test.AssertionFailedError;
-import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.MediumTest;
-import com.android.org.conscrypt.NativeConstants;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-/**
- * Junit / Instrumentation test case for KeyStore class
- *
- * Running the test suite:
- *
- *  runtest keystore-unit
- *
- * Or this individual test case:
- *
- *  runtest --path frameworks/base/keystore/tests/src/android/security/KeyStoreTest.java
- */
-@MediumTest
-public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
-    private static final String TEST_PASSWD = "12345678";
-    private static final String TEST_PASSWD2 = "87654321";
-    private static final String TEST_KEYNAME = "test-key";
-    private static final String TEST_KEYNAME1 = "test-key.1";
-    private static final String TEST_KEYNAME2 = "test-key\02";
-    private static final byte[] TEST_KEYVALUE = "test value".getBytes(StandardCharsets.UTF_8);
-
-    // "Hello, World" in Chinese
-    private static final String TEST_I18N_KEY = "\u4F60\u597D, \u4E16\u754C";
-    private static final byte[] TEST_I18N_VALUE = TEST_I18N_KEY.getBytes(StandardCharsets.UTF_8);
-
-    // Test vector data for signatures
-    private static final int RSA_KEY_SIZE = 1024;
-    private static final byte[] TEST_DATA =  new byte[RSA_KEY_SIZE / 8];
-    static {
-        for (int i = 0; i < TEST_DATA.length; i++) {
-            TEST_DATA[i] = (byte) i;
-        }
-    }
-
-    private KeyStore mKeyStore = null;
-
-    public KeyStoreTest() {
-        super(Activity.class);
-    }
-
-    private static final byte[] PRIVKEY_BYTES = hexToBytes(
-            "308204BE020100300D06092A864886F70D0101010500048204A8308204A4020100028201" +
-            "0100E0473E8AB8F2284FEB9E742FF9748FA118ED98633C92F52AEB7A2EBE0D3BE60329BE" +
-            "766AD10EB6A515D0D2CFD9BEA7930F0C306537899F7958CD3E85B01F8818524D312584A9" +
-            "4B251E3625B54141EDBFEE198808E1BB97FC7CB49B9EAAAF68E9C98D7D0EDC53BBC0FA00" +
-            "34356D6305FBBCC3C7001405386ABBC873CB0F3EF7425F3D33DF7B315AE036D2A0B66AFD" +
-            "47503B169BF36E3B5162515B715FDA83DEAF2C58AEB9ABFB3097C3CC9DD9DBE5EF296C17" +
-            "6139028E8A671E63056D45F40188D2C4133490845DE52C2534E9C6B2478C07BDAE928823" +
-            "B62D066C7770F9F63F3DBA247F530844747BE7AAA85D853B8BD244ACEC3DE3C89AB46453" +
-            "AB4D24C3AC6902030100010282010037784776A5F17698F5AC960DFB83A1B67564E648BD" +
-            "0597CF8AB8087186F2669C27A9ECBDD480F0197A80D07309E6C6A96F925331E57F8B4AC6" +
-            "F4D45EDA45A23269C09FC428C07A4E6EDF738A15DEC97FABD2F2BB47A14F20EA72FCFE4C" +
-            "36E01ADA77BD137CD8D4DA10BB162E94A4662971F175F985FA188F056CB97EE2816F43AB" +
-            "9D3747612486CDA8C16196C30818A995EC85D38467791267B3BF21F273710A6925862576" +
-            "841C5B6712C12D4BD20A2F3299ADB7C135DA5E9515ABDA76E7CAF2A3BE80551D073B78BF" +
-            "1162C48AD2B7F4743A0238EE4D252F7D5E7E6533CCAE64CCB39360075A2FD1E034EC3AE5" +
-            "CE9C408CCBF0E25E4114021687B3DD4754AE8102818100F541884BC3737B2922D4119EF4" +
-            "5E2DEE2CD4CBB75F45505A157AA5009F99C73A2DF0724AC46024306332EA898177634546" +
-            "5DC6DF1E0A6F140AFF3B7396E6A8994AC5DAA96873472FE37749D14EB3E075E629DBEB35" +
-            "83338A6F3649D0A2654A7A42FD9AB6BFA4AC4D481D390BB229B064BDC311CC1BE1B63189" +
-            "DA7C40CDECF2B102818100EA1A742DDB881CEDB7288C87E38D868DD7A409D15A43F445D5" +
-            "377A0B5731DDBFCA2DAF28A8E13CD5C0AFCEC3347D74A39E235A3CD9633F274DE2B94F92" +
-            "DF43833911D9E9F1CF58F27DE2E08FF45964C720D3EC2139DC7CAFC912953CDECB2F355A" +
-            "2E2C35A50FAD754CB3B23166424BA3B6E3112A2B898C38C5C15EDB238693390281805182" +
-            "8F1EC6FD996029901BAF1D7E337BA5F0AF27E984EAD895ACE62BD7DF4EE45A224089F2CC" +
-            "151AF3CD173FCE0474BCB04F386A2CDCC0E0036BA2419F54579262D47100BE931984A3EF" +
-            "A05BECF141574DC079B3A95C4A83E6C43F3214D6DF32D512DE198085E531E616B83FD7DD" +
-            "9D1F4E2607C3333D07C55D107D1D3893587102818100DB4FB50F50DE8EDB53FF34C80931" +
-            "88A0512867DA2CCA04897759E587C244010DAF8664D59E8083D16C164789301F67A9F078" +
-            "060D834A2ADBD367575B68A8A842C2B02A89B3F31FCCEC8A22FE395795C5C6C7422B4E5D" +
-            "74A1E9A8F30E7759B9FC2D639C1F15673E84E93A5EF1506F4315383C38D45CBD1B14048F" +
-            "4721DC82326102818100D8114593AF415FB612DBF1923710D54D07486205A76A3B431949" +
-            "68C0DFF1F11EF0F61A4A337D5FD3741BBC9640E447B8B6B6C47C3AC1204357D3B0C55BA9" +
-            "286BDA73F629296F5FA9146D8976357D3C751E75148696A40B74685C82CE30902D639D72" +
-            "4FF24D5E2E9407EE34EDED2E3B4DF65AA9BCFEB6DF28D07BA6903F165768");
-
-    private static final byte[] AES256_BYTES = hexToBytes(
-            "0CC175B9C0F1B6A831C399E269772661CEC520EA51EA0A47E87295FA3245A605");
-
-    private static byte[] hexToBytes(String s) {
-        int len = s.length();
-        byte[] data = new byte[len / 2];
-        for (int i = 0; i < len; i += 2) {
-            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(
-                    s.charAt(i + 1), 16));
-        }
-        return data;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        mKeyStore = KeyStore.getInstance();
-        if (mKeyStore.state() != KeyStore.State.UNINITIALIZED) {
-            mKeyStore.reset();
-        }
-        assertEquals("KeyStore should be in an uninitialized state",
-                KeyStore.State.UNINITIALIZED, mKeyStore.state());
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mKeyStore.reset();
-        super.tearDown();
-    }
-
-    public void testState() throws Exception {
-        assertEquals(KeyStore.State.UNINITIALIZED, mKeyStore.state());
-    }
-
-    public void testPassword() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
-    }
-
-    public void testGet() throws Exception {
-        assertNull(mKeyStore.get(TEST_KEYNAME));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertNull(mKeyStore.get(TEST_KEYNAME));
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-    }
-
-    public void testPut() throws Exception {
-        assertNull(mKeyStore.get(TEST_KEYNAME));
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-    }
-
-    public void testPut_grantedUid_Wifi() throws Exception {
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testPut_ungrantedUid_Bluetooth() throws Exception {
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-    }
-
-    public void testI18n() throws Exception {
-        assertFalse(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_I18N_KEY));
-        mKeyStore.onUserPasswordChanged(TEST_I18N_KEY);
-        assertTrue(mKeyStore.put(TEST_I18N_KEY, TEST_I18N_VALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_I18N_KEY));
-    }
-
-    public void testDelete() throws Exception {
-        assertFalse(mKeyStore.delete(TEST_KEYNAME));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertFalse(mKeyStore.delete(TEST_KEYNAME));
-
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-        assertTrue(mKeyStore.delete(TEST_KEYNAME));
-        assertNull(mKeyStore.get(TEST_KEYNAME));
-    }
-
-    public void testDelete_grantedUid_Wifi() throws Exception {
-        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
-
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertTrue(mKeyStore.delete(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testDelete_ungrantedUid_Bluetooth() throws Exception {
-        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
-
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.delete(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-    }
-
-    public void testContains() throws Exception {
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testContains_grantedUid_Wifi() throws Exception {
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.WIFI_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testContains_grantedUid_Bluetooth() throws Exception {
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-
-        assertFalse(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, Process.BLUETOOTH_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-    }
-
-    public void testList() throws Exception {
-        String[] emptyResult = mKeyStore.list(TEST_KEYNAME);
-        assertNotNull(emptyResult);
-        assertEquals(0, emptyResult.length);
-
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
-        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
-
-        String[] results = mKeyStore.list(TEST_KEYNAME);
-        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
-                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
-                     new HashSet(Arrays.asList(results)));
-    }
-
-    public void testList_ungrantedUid_Bluetooth() throws Exception {
-        String[] results1 = mKeyStore.list(TEST_KEYNAME, Process.BLUETOOTH_UID);
-        assertEquals(0, results1.length);
-
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
-        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
-
-        String[] results2 = mKeyStore.list(TEST_KEYNAME, Process.BLUETOOTH_UID);
-        assertEquals(0, results2.length);
-    }
-
-    public void testList_grantedUid_Wifi() throws Exception {
-        String[] results1 = mKeyStore.list(TEST_KEYNAME, Process.WIFI_UID);
-        assertNotNull(results1);
-        assertEquals(0, results1.length);
-
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
-        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED);
-
-        String[] results2 = mKeyStore.list(TEST_KEYNAME, Process.WIFI_UID);
-        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
-                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
-                     new HashSet(Arrays.asList(results2)));
-    }
-
-    public void testList_grantedUid_Vpn() throws Exception {
-        String[] results1 = mKeyStore.list(TEST_KEYNAME, Process.VPN_UID);
-        assertNotNull(results1);
-        assertEquals(0, results1.length);
-
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        mKeyStore.put(TEST_KEYNAME1, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
-        mKeyStore.put(TEST_KEYNAME2, TEST_KEYVALUE, Process.VPN_UID, KeyStore.FLAG_ENCRYPTED);
-
-        String[] results2 = mKeyStore.list(TEST_KEYNAME, Process.VPN_UID);
-        assertEquals(new HashSet(Arrays.asList(TEST_KEYNAME1.substring(TEST_KEYNAME.length()),
-                                               TEST_KEYNAME2.substring(TEST_KEYNAME.length()))),
-                     new HashSet(Arrays.asList(results2)));
-    }
-
-    public void testLock() throws Exception {
-        assertFalse(mKeyStore.lock());
-
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
-
-        assertTrue(mKeyStore.lock());
-        assertEquals(KeyStore.State.LOCKED, mKeyStore.state());
-    }
-
-    public void testUnlock() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertEquals(KeyStore.State.UNLOCKED, mKeyStore.state());
-        mKeyStore.lock();
-
-        assertFalse(mKeyStore.unlock(TEST_PASSWD2));
-        assertTrue(mKeyStore.unlock(TEST_PASSWD));
-    }
-
-    public void testIsEmpty() throws Exception {
-        assertTrue(mKeyStore.isEmpty());
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        assertTrue(mKeyStore.isEmpty());
-        mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED);
-        assertFalse(mKeyStore.isEmpty());
-        mKeyStore.reset();
-        assertTrue(mKeyStore.isEmpty());
-    }
-
-    public void testGenerate_NotInitialized_Fail() throws Exception {
-        assertFalse("Should fail when keystore is not initialized",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-    }
-
-    public void testGenerate_Locked_Fail() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        mKeyStore.lock();
-        assertFalse("Should fail when keystore is locked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-    }
-
-    public void testGenerate_Success() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testGenerate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
-                    NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testImport_Success() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testImport_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testImport_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertFalse(mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES, Process.BLUETOOTH_UID,
-                KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testImport_Failure_BadEncoding() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-
-        assertFalse("Invalid DER-encoded key should not be imported", mKeyStore.importKey(
-                TEST_KEYNAME, TEST_DATA, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-    }
-
-    public void testSign_Success() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
-
-        assertNotNull("Signature should not be null", signature);
-    }
-
-    public void testVerify_Success() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
-
-        assertNotNull("Signature should not be null", signature);
-
-        assertTrue("Signature should verify with same data",
-                mKeyStore.verify(TEST_KEYNAME, TEST_DATA, signature));
-    }
-
-    public void testSign_NotInitialized_Failure() throws Exception {
-        assertNull("Should not be able to sign without first initializing the keystore",
-                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
-    }
-
-    public void testSign_NotGenerated_Failure() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-
-        assertNull("Should not be able to sign without first generating keys",
-                mKeyStore.sign(TEST_KEYNAME, TEST_DATA));
-    }
-
-    public void testGrant_Generated_Success() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue("Should be able to grant key to other user",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-    }
-
-    public void testGrant_Imported_Success() throws Exception {
-        assertTrue("Password should work for keystore", mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should be able to grant key to other user", mKeyStore.grant(TEST_KEYNAME, 0));
-    }
-
-    public void testGrant_NoKey_Failure() throws Exception {
-        assertTrue("Should be able to unlock keystore for test",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertFalse("Should not be able to grant without first initializing the keystore",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-    }
-
-    public void testGrant_NotInitialized_Failure() throws Exception {
-        assertFalse("Should not be able to grant without first initializing the keystore",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_Generated_Success() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue("Should be able to grant key to other user",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-
-        assertTrue("Should be able to ungrant key to other user",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_Imported_Success() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key for testcase", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should be able to grant key to other user",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-
-        assertTrue("Should be able to ungrant key to other user",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_NotInitialized_Failure() throws Exception {
-        assertFalse("Should fail to ungrant key when keystore not initialized",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_NoGrant_Failure() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertFalse("Should not be able to revoke not existent grant",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_DoubleUngrant_Failure() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue("Should be able to grant key to other user",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-
-        assertTrue("Should be able to ungrant key to other user",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-
-        assertFalse("Should fail to ungrant key to other user second time",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testUngrant_DoubleGrantUngrant_Failure() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                        RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue("Should be able to grant key to other user",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-
-        assertTrue("Should be able to grant key to other user a second time",
-                mKeyStore.grant(TEST_KEYNAME, 0));
-
-        assertTrue("Should be able to ungrant key to other user",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-
-        assertFalse("Should fail to ungrant key to other user second time",
-                mKeyStore.ungrant(TEST_KEYNAME, 0));
-    }
-
-    public void testDuplicate_grantedUid_Wifi_Success() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-
-        // source doesn't exist
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, -1, TEST_KEYNAME1, Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
-
-        // Copy from current UID to granted UID
-        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME1, Process.WIFI_UID));
-
-        // Copy from granted UID to same granted UID
-        assertTrue(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
-                Process.WIFI_UID));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME1, Process.WIFI_UID));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME2, Process.WIFI_UID));
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME1, Process.WIFI_UID, TEST_KEYNAME2,
-                Process.WIFI_UID));
-
-        assertTrue(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME1));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME2));
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, -1));
-    }
-
-    public void testDuplicate_ungrantedUid_Bluetooth_Failure() throws Exception {
-        assertTrue(mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
-                    RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
-
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, -1, TEST_KEYNAME2, Process.BLUETOOTH_UID));
-        assertFalse(mKeyStore.duplicate(TEST_KEYNAME, Process.BLUETOOTH_UID, TEST_KEYNAME2,
-                Process.BLUETOOTH_UID));
-
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
-    }
-
-    /**
-     * The amount of time to allow before and after expected time for variance
-     * in timing tests.
-     */
-    private static final long SLOP_TIME_MILLIS = 15000L;
-
-    public void testGetmtime_Success() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        long now = System.currentTimeMillis();
-        long actual = mKeyStore.getmtime(TEST_KEYNAME);
-
-        long expectedAfter = now - SLOP_TIME_MILLIS;
-        long expectedBefore = now + SLOP_TIME_MILLIS;
-
-        assertLessThan("Time should be close to current time", expectedBefore, actual);
-        assertGreaterThan("Time should be close to current time", expectedAfter, actual);
-    }
-
-    private static void assertLessThan(String explanation, long expectedBefore, long actual) {
-        if (actual >= expectedBefore) {
-            throw new AssertionFailedError(explanation + ": actual=" + actual
-                    + ", expected before: " + expectedBefore);
-        }
-    }
-
-    private static void assertGreaterThan(String explanation, long expectedAfter, long actual) {
-        if (actual <= expectedAfter) {
-            throw new AssertionFailedError(explanation + ": actual=" + actual
-                    + ", expected after: " + expectedAfter);
-        }
-    }
-
-    public void testGetmtime_NonExist_Failure() throws Exception {
-        assertTrue("Password should work for keystore",
-                mKeyStore.onUserPasswordChanged(TEST_PASSWD));
-
-        assertTrue("Should be able to import key when unlocked", mKeyStore.importKey(TEST_KEYNAME,
-                PRIVKEY_BYTES, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertEquals("-1 should be returned for non-existent key",
-                -1L, mKeyStore.getmtime(TEST_KEYNAME2));
-    }
-
-    private KeyCharacteristics generateRsaKey(String name) throws Exception {
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
-        args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
-        assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
-        return outCharacteristics;
-    }
-
-    public void testGenerateKey() throws Exception {
-        generateRsaKey("test");
-        mKeyStore.delete("test");
-    }
-
-    public void testGenerateRsaWithEntropy() throws Exception {
-        byte[] entropy = new byte[] {1,2,3,4,5};
-        String name = "test";
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
-        args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int result = mKeyStore.generateKey(name, args, entropy, 0, outCharacteristics);
-        assertEquals("generateKey should succeed", KeyStore.NO_ERROR, result);
-    }
-
-    public void testGenerateAndDelete() throws Exception {
-        generateRsaKey("test");
-        assertTrue("delete should succeed", mKeyStore.delete("test"));
-    }
-
-    public void testGetKeyCharacteristicsSuccess() throws Exception {
-        mKeyStore.onUserPasswordChanged(TEST_PASSWD);
-        String name = "test";
-        KeyCharacteristics gen = generateRsaKey(name);
-        KeyCharacteristics call = new KeyCharacteristics();
-        int result = mKeyStore.getKeyCharacteristics(name, null, null, call);
-        assertEquals("getKeyCharacteristics should succeed", KeyStore.NO_ERROR, result);
-        mKeyStore.delete("test");
-    }
-
-    public void testAppId() throws Exception {
-        String name = "test";
-        byte[] id = new byte[] {0x01, 0x02, 0x03};
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        args.addBytes(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
-        args.addUnsignedLong(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT, RSAKeyGenParameterSpec.F4);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int result = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
-        assertEquals("generateRsaKey should succeed", KeyStore.NO_ERROR, result);
-        assertEquals("getKeyCharacteristics should fail without application ID",
-                KeymasterDefs.KM_ERROR_INVALID_KEY_BLOB,
-                mKeyStore.getKeyCharacteristics(name, null, null, outCharacteristics));
-        assertEquals("getKeyCharacteristics should succeed with application ID",
-                KeyStore.NO_ERROR,
-                mKeyStore.getKeyCharacteristics(name, new KeymasterBlob(id), null,
-                    outCharacteristics));
-    }
-
-
-    public void testExportRsa() throws Exception {
-        String name = "test";
-        generateRsaKey(name);
-        ExportResult result = mKeyStore.exportKey(name, KeymasterDefs.KM_KEY_FORMAT_X509, null,
-                null);
-        assertEquals("Export success", KeyStore.NO_ERROR, result.resultCode);
-        // TODO: Verify we have an RSA public key that's well formed.
-    }
-
-    public void testAesGcmEncryptSuccess() throws Exception {
-        String name = "test";
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
-        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
-
-        args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 128);
-        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
-                true, args, null);
-        IBinder token = result.token;
-        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
-        result = mKeyStore.update(token, null, new byte[] {0x01, 0x02, 0x03, 0x04});
-        assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
-        assertEquals("Finish should succeed", KeyStore.NO_ERROR,
-                mKeyStore.finish(token, null, null).resultCode);
-        // TODO: Assert that an AEAD tag was returned by finish
-    }
-
-    public void testBadToken() throws Exception {
-        IBinder token = new Binder();
-        OperationResult result = mKeyStore.update(token, null, new byte[] {0x01});
-        assertEquals("Update with invalid token should fail",
-                KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, result.resultCode);
-    }
-
-    private int importAesKey(String name, byte[] key, int size, int mode) {
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, mode);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, size);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-        return mKeyStore.importKey(name, args, KeymasterDefs.KM_KEY_FORMAT_RAW, key, 0,
-                new KeyCharacteristics());
-    }
-    private byte[] doOperation(String name, int purpose, byte[] in, KeymasterArguments beginArgs) {
-        OperationResult result = mKeyStore.begin(name, purpose,
-                true, beginArgs, null);
-        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
-        IBinder token = result.token;
-        result = mKeyStore.update(token, null, in);
-        assertEquals("Update should succeed", KeyStore.NO_ERROR, result.resultCode);
-        assertEquals("All data should be consumed", in.length, result.inputConsumed);
-        assertEquals("Finish should succeed", KeyStore.NO_ERROR,
-                mKeyStore.finish(token, null, null).resultCode);
-        return result.output;
-    }
-
-    public void testImportAes() throws Exception {
-        int result = importAesKey("aes", AES256_BYTES, 256, KeymasterDefs.KM_MODE_ECB);
-        assertEquals("import should succeed", KeyStore.NO_ERROR, result);
-        mKeyStore.delete("aes");
-    }
-
-    public void testAes256Ecb() throws Exception {
-        byte[] key =
-                hexToBytes("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
-        String name = "aes";
-        assertEquals(KeyStore.NO_ERROR, importAesKey(name, key, 256, KeymasterDefs.KM_MODE_ECB));
-        byte[][] testVectors = new byte[][] {
-            hexToBytes("6bc1bee22e409f96e93d7e117393172a"),
-            hexToBytes("ae2d8a571e03ac9c9eb76fac45af8e51"),
-            hexToBytes("30c81c46a35ce411e5fbc1191a0a52ef"),
-            hexToBytes("f69f2445df4f9b17ad2b417be66c3710")};
-        byte[][] cipherVectors = new byte[][] {
-            hexToBytes("f3eed1bdb5d2a03c064b5a7e3db181f8"),
-            hexToBytes("591ccb10d410ed26dc5ba74a31362870"),
-            hexToBytes("b6ed21b99ca6f4f9f153e7b1beafed1d"),
-            hexToBytes("23304b7a39f9f3ff067d8d8f9e24ecc7")};
-        KeymasterArguments beginArgs = new KeymasterArguments();
-        beginArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        beginArgs.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
-        beginArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        for (int i = 0; i < testVectors.length; i++) {
-            byte[] cipherText = doOperation(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, testVectors[i],
-                    beginArgs);
-            MoreAsserts.assertEquals(cipherVectors[i], cipherText);
-        }
-        for (int i = 0; i < testVectors.length; i++) {
-            byte[] plainText = doOperation(name, KeymasterDefs.KM_PURPOSE_DECRYPT,
-                    cipherVectors[i], beginArgs);
-            MoreAsserts.assertEquals(testVectors[i], plainText);
-        }
-    }
-
-    // This is a very implementation specific test and should be thrown out eventually, however it
-    // is nice for now to test that keystore is properly pruning operations.
-    public void testOperationPruning() throws Exception {
-        String name = "test";
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
-        args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
-        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
-
-        args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
-        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
-                true, args, null);
-        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
-        IBinder first = result.token;
-        // Implementation detail: softkeymaster supports 16 concurrent operations
-        for (int i = 0; i < 16; i++) {
-            result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT, true, args, null);
-            assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
-        }
-        // At this point the first operation should be pruned.
-        assertEquals("Operation should be pruned", KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE,
-                mKeyStore.update(first, null, new byte[] {0x01}).resultCode);
-    }
-
-    public void testAuthNeeded() throws Exception {
-        String name = "test";
-        KeymasterArguments args = new KeymasterArguments();
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
-        args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_AES);
-        args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
-        args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, 256);
-        args.addEnum(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
-        args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 1);
-
-        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
-        int rc = mKeyStore.generateKey(name, args, null, 0, outCharacteristics);
-        assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
-        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
-                true, args, null);
-        assertEquals("Begin should expect authorization", KeyStore.OP_AUTH_NEEDED,
-                result.resultCode);
-        IBinder token = result.token;
-        result = mKeyStore.update(token, null, new byte[] {0x01, 0x02, 0x03, 0x04});
-        assertEquals("Update should require authorization",
-                KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED, result.resultCode);
-    }
-
-    public void testPasswordRemovalEncryptedEntry() throws Exception {
-        mKeyStore.onUserPasswordChanged("test");
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-        mKeyStore.onUserPasswordChanged("");
-        // Removing the password should have deleted all entries using FLAG_ENCRYPTED
-        assertNull(mKeyStore.get(TEST_KEYNAME));
-        assertFalse(mKeyStore.contains(TEST_KEYNAME));
-    }
-
-    public void testPasswordRemovalUnencryptedEntry() throws Exception {
-        mKeyStore.onUserPasswordChanged("test");
-        assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE, KeyStore.UID_SELF,
-                KeyStore.FLAG_NONE));
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-        mKeyStore.onUserPasswordChanged("");
-        // Removing the password should not delete unencrypted entries.
-        assertTrue(mKeyStore.contains(TEST_KEYNAME));
-        assertTrue(Arrays.equals(TEST_KEYVALUE, mKeyStore.get(TEST_KEYNAME)));
-    }
-}
diff --git a/keystore/tests/src/android/security/SystemKeyStoreTest.java b/keystore/tests/src/android/security/SystemKeyStoreTest.java
deleted file mode 100644
index ecf7cbc..0000000
--- a/keystore/tests/src/android/security/SystemKeyStoreTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security;
-
-import android.app.Activity;
-import android.security.SystemKeyStore;
-import android.test.ActivityUnitTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-/**
- * Junit / Instrumentation test case for KeyStore class
- *
- * Running the test suite:
- *
- *  runtest keystore-unit
- *
- * Or this individual test case:
- *
- *  runtest --path frameworks/base/keystore/tests/src/android/security/SystemKeyStoreTest.java
- */
-@MediumTest
-public class SystemKeyStoreTest extends ActivityUnitTestCase<Activity> {
-
-    private static final String keyName = "TestKey";
-    private static final String keyName2 = "TestKey2";
-    private SystemKeyStore mSysKeyStore = null;
-
-    public SystemKeyStoreTest() {
-        super(Activity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        mSysKeyStore = SystemKeyStore.getInstance();
-        try {
-            mSysKeyStore.deleteKey(keyName);
-            mSysKeyStore.deleteKey(keyName2);
-        } catch (Exception e) { }
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        try {
-            mSysKeyStore.deleteKey(keyName);
-            mSysKeyStore.deleteKey(keyName2);
-        } catch (Exception e) { }
-        super.tearDown();
-    }
-
-    public void testBasicAccess() throws Exception {
-        try {
-            byte[] newKey = mSysKeyStore.generateNewKey(128, "AES", keyName);
-            assertNotNull(newKey);
-            byte[] recKey = mSysKeyStore.retrieveKey(keyName);
-            assertEquals(newKey.length, recKey.length);
-            for (int i = 0; i < newKey.length; i++) {
-                assertEquals(newKey[i], recKey[i]);
-            }
-            mSysKeyStore.deleteKey(keyName);
-            byte[] nullKey = mSysKeyStore.retrieveKey(keyName);
-            assertNull(nullKey);
-
-            String newKeyStr = mSysKeyStore.generateNewKeyHexString(128, "AES", keyName2);
-            assertNotNull(newKeyStr);
-            String recKeyStr = mSysKeyStore.retrieveKeyHexString(keyName2);
-            assertEquals(newKeyStr, recKeyStr);
-
-            mSysKeyStore.deleteKey(keyName2);
-            String nullKey2 = mSysKeyStore.retrieveKeyHexString(keyName2);
-            assertNull(nullKey2);
-        } catch (Exception e) {
-            fail();
-        }
-    }
-}
diff --git a/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java
deleted file mode 100644
index 1af0b7d..0000000
--- a/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keystore;
-
-import android.security.Credentials;
-import android.security.KeyPairGeneratorSpec;
-import android.security.KeyStore;
-import android.security.keymaster.ExportResult;
-import android.security.keymaster.KeymasterDefs;
-import android.test.AndroidTestCase;
-
-import java.io.ByteArrayInputStream;
-import java.math.BigInteger;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-
-import javax.security.auth.x500.X500Principal;
-
-public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
-    private android.security.KeyStore mAndroidKeyStore;
-
-    private java.security.KeyPairGenerator mGenerator;
-
-    private static final String TEST_ALIAS_1 = "test1";
-
-    private static final String TEST_ALIAS_2 = "test2";
-
-    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
-
-    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
-
-    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
-
-    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
-
-    private static final long NOW_MILLIS = System.currentTimeMillis();
-
-    /* We have to round this off because X509v3 doesn't store milliseconds. */
-    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
-
-    @SuppressWarnings("deprecation")
-    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
-
-    @Override
-    protected void setUp() throws Exception {
-        mAndroidKeyStore = android.security.KeyStore.getInstance();
-
-        assertTrue(mAndroidKeyStore.reset());
-
-        assertFalse(mAndroidKeyStore.isUnlocked());
-
-        mGenerator = java.security.KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
-    }
-
-    private void setupPassword() {
-        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
-        assertTrue(mAndroidKeyStore.isUnlocked());
-
-        String[] aliases = mAndroidKeyStore.list("");
-        assertNotNull(aliases);
-        assertEquals(0, aliases.length);
-    }
-
-    public void testKeyPairGenerator_Initialize_Params_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .setEncryptionRequired()
-                .build());
-    }
-
-    public void testKeyPairGenerator_Initialize_KeySize_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        try {
-            mGenerator.initialize(1024);
-            fail("KeyPairGenerator should not support setting the key size");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Encrypted_Failure()
-            throws Exception {
-        setupPassword();
-
-        try {
-            mGenerator.initialize(1024, new SecureRandom());
-            fail("KeyPairGenerator should not support setting the key size");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Encrypted_Failure()
-            throws Exception {
-        setupPassword();
-
-        mGenerator.initialize(
-                new KeyPairGeneratorSpec.Builder(getContext())
-                        .setAlias(TEST_ALIAS_1)
-                        .setKeyType("RSA")
-                        .setKeySize(1024)
-                        .setSubject(TEST_DN_1)
-                        .setSerialNumber(TEST_SERIAL_1)
-                        .setStartDate(NOW)
-                        .setEndDate(NOW_PLUS_10_YEARS)
-                        .setEncryptionRequired()
-                        .build(),
-                new SecureRandom());
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .setEncryptionRequired()
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
-        KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "AndroidKeyStore");
-        generator.initialize(new KeyGenParameterSpec.Builder(
-                TEST_ALIAS_1,
-                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
-                .setCertificateSubject(TEST_DN_1)
-                .setCertificateSerialNumber(TEST_SERIAL_1)
-                .setCertificateNotBefore(NOW)
-                .setCertificateNotAfter(NOW_PLUS_10_YEARS)
-                .setDigests(KeyProperties.DIGEST_SHA256)
-                .build());
-
-        final KeyPair pair = generator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_Legacy_GenerateKeyPair_EC_Unencrypted_Success()
-            throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("EC")
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("EC")
-                .setKeySize(521)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success()
-            throws Exception {
-        AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3L));
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeySize(1024)
-                .setAlgorithmParameterSpec(spec)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 1024, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
-        // Generate the first key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_1)
-                    .setSubject(TEST_DN_1)
-                    .setSerialNumber(TEST_SERIAL_1)
-                    .setStartDate(NOW)
-                    .setEndDate(NOW_PLUS_10_YEARS)
-                    .build());
-            final KeyPair pair1 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair1);
-            assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-
-        // Replace the original key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_2)
-                    .setSubject(TEST_DN_2)
-                    .setSerialNumber(TEST_SERIAL_2)
-                    .setStartDate(NOW)
-                    .setEndDate(NOW_PLUS_10_YEARS)
-                    .build());
-            final KeyPair pair2 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair2);
-            assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_Replaced_UnencryptedToEncrypted_Success()
-            throws Exception {
-        // Generate the first key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_1)
-                    .setSubject(TEST_DN_1)
-                    .setSerialNumber(TEST_SERIAL_1)
-                    .setStartDate(NOW)
-                    .setEndDate(NOW_PLUS_10_YEARS)
-                    .build());
-            final KeyPair pair1 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair1);
-            assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-
-        // Attempt to replace previous key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_1)
-                    .setSubject(TEST_DN_2)
-                    .setSerialNumber(TEST_SERIAL_2)
-                    .setStartDate(NOW)
-                    .setEndDate(NOW_PLUS_10_YEARS)
-                    .setEncryptionRequired()
-                    .build());
-            try {
-                mGenerator.generateKeyPair();
-                fail("Should not be able to generate encrypted key while not initialized");
-            } catch (IllegalStateException expected) {
-            }
-
-            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
-            assertTrue(mAndroidKeyStore.isUnlocked());
-
-            final KeyPair pair2 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair2);
-            assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-    }
-
-    private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
-            AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
-            throws Exception {
-        final PublicKey pubKey = pair.getPublic();
-        assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
-        assertEquals(keyType, pubKey.getAlgorithm());
-
-        if ("EC".equalsIgnoreCase(keyType)) {
-            assertEquals("Curve should be what was specified during initialization", keySize,
-                    ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
-        } else if ("RSA".equalsIgnoreCase(keyType)) {
-            RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
-            assertEquals("Modulus size should be what is specified during initialization",
-                    (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
-            if (spec != null) {
-                RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
-                assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
-                assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
-            }
-        }
-
-        final PrivateKey privKey = pair.getPrivate();
-        assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
-        assertEquals(keyType, privKey.getAlgorithm());
-
-        if ("EC".equalsIgnoreCase(keyType)) {
-            assertTrue("EC private key must be instanceof ECKey: " + privKey.getClass().getName(),
-                    privKey instanceof ECKey);
-            assertEquals("Private and public key must have the same EC parameters",
-                    ((ECKey) pubKey).getParams(), ((ECKey) privKey).getParams());
-        } else if ("RSA".equalsIgnoreCase(keyType)) {
-            assertTrue("RSA private key must be instance of RSAKey: "
-                    + privKey.getClass().getName(),
-                    privKey instanceof RSAKey);
-            assertEquals("Private and public key must have the same RSA modulus",
-                    ((RSAKey) pubKey).getModulus(), ((RSAKey) privKey).getModulus());
-        }
-
-        final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
-        assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
-
-        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        final Certificate userCert =
-                cf.generateCertificate(new ByteArrayInputStream(userCertBytes));
-
-        assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
-
-        final X509Certificate x509userCert = (X509Certificate) userCert;
-
-        assertEquals(
-                "Public key used to sign certificate should have the same algorithm as in KeyPair",
-                pubKey.getAlgorithm(), x509userCert.getPublicKey().getAlgorithm());
-
-        assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
-                pubKey,
-                AndroidKeyStoreProvider.getAndroidKeyStorePublicKey(
-                        Credentials.USER_PRIVATE_KEY + alias,
-                        KeyStore.UID_SELF,
-                        x509userCert.getPublicKey().getAlgorithm(),
-                        x509userCert.getPublicKey().getEncoded()));
-
-        assertEquals("The Subject DN should be the one passed into the params", dn,
-                x509userCert.getSubjectDN());
-
-        assertEquals("The Issuer DN should be the same as the Subject DN", dn,
-                x509userCert.getIssuerDN());
-
-        assertEquals("The Serial should be the one passed into the params", serial,
-                x509userCert.getSerialNumber());
-
-        assertDateEquals("The notBefore date should be the one passed into the params", start,
-                x509userCert.getNotBefore());
-
-        assertDateEquals("The notAfter date should be the one passed into the params", end,
-                x509userCert.getNotAfter());
-
-        // Assert that the cert's signature verifies using the public key from generated KeyPair
-        x509userCert.verify(pubKey);
-        // Assert that the cert's signature verifies using the public key from the cert itself.
-        x509userCert.verify(x509userCert.getPublicKey());
-
-        final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias);
-        assertNull("A list of CA certificates should not exist for the generated entry", caCerts);
-
-        ExportResult exportResult = mAndroidKeyStore.exportKey(
-                Credentials.USER_PRIVATE_KEY + alias, KeymasterDefs.KM_KEY_FORMAT_X509, null, null);
-        assertEquals(KeyStore.NO_ERROR, exportResult.resultCode);
-        final byte[] pubKeyBytes = exportResult.exportData;
-        assertNotNull("The keystore should return the public key for the generated key",
-                pubKeyBytes);
-        assertTrue("Public key X.509 format should be as expected",
-                Arrays.equals(pubKey.getEncoded(), pubKeyBytes));
-    }
-
-    private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
-        SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
-
-        String result1 = formatter.format(date1);
-        String result2 = formatter.format(date2);
-
-        assertEquals(message, result1, result2);
-    }
-}
diff --git a/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java
deleted file mode 100644
index aa718dc..0000000
--- a/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java
+++ /dev/null
@@ -1,2210 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.security.keystore;
-
-import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-
-import com.android.org.conscrypt.NativeConstants;
-
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.security.KeyStoreParameter;
-import android.test.AndroidTestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyStore.Entry;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStore.TrustedCertificateEntry;
-import java.security.KeyStoreException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.RSAKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.security.auth.x500.X500Principal;
-
-public class AndroidKeyStoreTest extends AndroidTestCase {
-    private android.security.KeyStore mAndroidKeyStore;
-
-    private java.security.KeyStore mKeyStore;
-
-    private static final String TEST_ALIAS_1 = "test1";
-
-    private static final String TEST_ALIAS_2 = "test2";
-
-    private static final String TEST_ALIAS_3 = "test3";
-
-    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
-
-    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
-
-    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
-
-    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
-
-    private static final long NOW_MILLIS = System.currentTimeMillis();
-
-    /* We have to round this off because X509v3 doesn't store milliseconds. */
-    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
-
-    @SuppressWarnings("deprecation")
-    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
-
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_RSA_CA_1 = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
-            (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
-            (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
-            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
-            (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
-            (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
-            (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
-            (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
-            (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
-            (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
-            (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
-            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
-            (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
-            (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
-            (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
-            (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
-            (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
-            (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
-            (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
-            (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
-            (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
-            (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
-            (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
-            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
-            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
-            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
-            (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
-            (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
-            (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
-            (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
-            (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
-            (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
-            (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
-            (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
-            (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
-            (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
-            (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
-            (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
-            (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
-            (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
-            (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
-            (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
-            (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
-            (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
-            (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
-            (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
-            (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
-            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
-            (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
-            (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
-            (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
-            (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
-            (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
-            (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
-            (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
-            (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
-            (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
-            (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
-            (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
-            (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
-            (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
-            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
-            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
-            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
-            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
-            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
-            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
-            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
-            (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
-            (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
-            (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
-            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
-            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
-            (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
-            (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
-            (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
-            (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
-            (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
-            (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
-            (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
-            (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
-            (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
-            (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
-            (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
-            (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
-            (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
-            (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
-            (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
-            (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
-            (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
-            (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
-            (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
-            (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
-            (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
-            (byte) 0xf1, (byte) 0x61
-    };
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-    };
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_RSA_USER_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
-            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
-            (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
-            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
-            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
-            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
-            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
-            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
-            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
-            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30, (byte) 0x1e,
-            (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32, (byte) 0x30, (byte) 0x38,
-            (byte) 0x31, (byte) 0x34, (byte) 0x32, (byte) 0x33, (byte) 0x32, (byte) 0x35,
-            (byte) 0x34, (byte) 0x38, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32,
-            (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x32,
-            (byte) 0x33, (byte) 0x32, (byte) 0x35, (byte) 0x34, (byte) 0x38, (byte) 0x5a,
-            (byte) 0x30, (byte) 0x55, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
-            (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
-            (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x1b,
-            (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
-            (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x54,
-            (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43, (byte) 0x61,
-            (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x31, (byte) 0x1c, (byte) 0x30,
-            (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
-            (byte) 0x13, (byte) 0x13, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
-            (byte) 0x65, (byte) 0x72, (byte) 0x31, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
-            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
-            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
-            (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
-            (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6,
-            (byte) 0x5b, (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c,
-            (byte) 0x66, (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86,
-            (byte) 0x8a, (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3,
-            (byte) 0x02, (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08,
-            (byte) 0xf3, (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04,
-            (byte) 0x6d, (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f,
-            (byte) 0x67, (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c,
-            (byte) 0xcb, (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30,
-            (byte) 0xe2, (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5,
-            (byte) 0x79, (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b,
-            (byte) 0xce, (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb,
-            (byte) 0x08, (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff,
-            (byte) 0x3b, (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9,
-            (byte) 0xc4, (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29,
-            (byte) 0x0d, (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b,
-            (byte) 0x23, (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78,
-            (byte) 0x08, (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5,
-            (byte) 0xf1, (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19,
-            (byte) 0xb4, (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03,
-            (byte) 0x16, (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce,
-            (byte) 0x9e, (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
-            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x7b, (byte) 0x30,
-            (byte) 0x79, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
-            (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86,
-            (byte) 0x48, (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01,
-            (byte) 0x0d, (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f,
-            (byte) 0x70, (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c,
-            (byte) 0x20, (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72,
-            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43,
-            (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69,
-            (byte) 0x63, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04,
-            (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x32, (byte) 0xa1, (byte) 0x1e,
-            (byte) 0x6b, (byte) 0x69, (byte) 0x04, (byte) 0xfe, (byte) 0xb3, (byte) 0xcd,
-            (byte) 0xf8, (byte) 0xbb, (byte) 0x14, (byte) 0xcd, (byte) 0xff, (byte) 0xd4,
-            (byte) 0x16, (byte) 0xc3, (byte) 0xab, (byte) 0x44, (byte) 0x2f, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23,
-            (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14,
-            (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60,
-            (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c,
-            (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e,
-            (byte) 0x5d, (byte) 0x51, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
-            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x46, (byte) 0x42, (byte) 0xef,
-            (byte) 0x56, (byte) 0x89, (byte) 0x78, (byte) 0x90, (byte) 0x38, (byte) 0x24,
-            (byte) 0x9f, (byte) 0x8c, (byte) 0x7a, (byte) 0xce, (byte) 0x7a, (byte) 0xa5,
-            (byte) 0xb5, (byte) 0x1e, (byte) 0x74, (byte) 0x96, (byte) 0x34, (byte) 0x49,
-            (byte) 0x8b, (byte) 0xed, (byte) 0x44, (byte) 0xb3, (byte) 0xc9, (byte) 0x05,
-            (byte) 0xd7, (byte) 0x48, (byte) 0x55, (byte) 0x52, (byte) 0x59, (byte) 0x15,
-            (byte) 0x0b, (byte) 0xaa, (byte) 0x16, (byte) 0x86, (byte) 0xd2, (byte) 0x8e,
-            (byte) 0x16, (byte) 0x99, (byte) 0xe8, (byte) 0x5f, (byte) 0x11, (byte) 0x71,
-            (byte) 0x42, (byte) 0x55, (byte) 0xd1, (byte) 0xc4, (byte) 0x6f, (byte) 0x2e,
-            (byte) 0xa9, (byte) 0x64, (byte) 0x6f, (byte) 0xd8, (byte) 0xfd, (byte) 0x43,
-            (byte) 0x13, (byte) 0x24, (byte) 0xaa, (byte) 0x67, (byte) 0xe6, (byte) 0xf5,
-            (byte) 0xca, (byte) 0x80, (byte) 0x5e, (byte) 0x3a, (byte) 0x3e, (byte) 0xcc,
-            (byte) 0x4f, (byte) 0xba, (byte) 0x87, (byte) 0xe6, (byte) 0xae, (byte) 0xbf,
-            (byte) 0x8f, (byte) 0xd5, (byte) 0x28, (byte) 0x38, (byte) 0x58, (byte) 0x30,
-            (byte) 0x24, (byte) 0xf6, (byte) 0x53, (byte) 0x5b, (byte) 0x41, (byte) 0x53,
-            (byte) 0xe6, (byte) 0x45, (byte) 0xbc, (byte) 0xbe, (byte) 0xe6, (byte) 0xbb,
-            (byte) 0x5d, (byte) 0xd8, (byte) 0xa7, (byte) 0xf9, (byte) 0x64, (byte) 0x99,
-            (byte) 0x04, (byte) 0x43, (byte) 0x75, (byte) 0xd7, (byte) 0x2d, (byte) 0x32,
-            (byte) 0x0a, (byte) 0x94, (byte) 0xaf, (byte) 0x06, (byte) 0x34, (byte) 0xae,
-            (byte) 0x46, (byte) 0xbd, (byte) 0xda, (byte) 0x00, (byte) 0x0e, (byte) 0x25,
-            (byte) 0xc2, (byte) 0xf7, (byte) 0xc9, (byte) 0xc3, (byte) 0x65, (byte) 0xd2,
-            (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
-    };
-
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl ecparam -name prime256v1 -out ecparam.pem
-     * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_EC_CA_1 = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x58, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xc1, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0xb2,
-            (byte) 0x8c, (byte) 0x04, (byte) 0x95, (byte) 0xeb, (byte) 0x10, (byte) 0xcb,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
-            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
-            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
-            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d,
-            (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37,
-            (byte) 0x31, (byte) 0x36, (byte) 0x32, (byte) 0x38, (byte) 0x32, (byte) 0x38,
-            (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30,
-            (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x32,
-            (byte) 0x38, (byte) 0x32, (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x45,
-            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
-            (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
-            (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
-            (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21,
-            (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74,
-            (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20,
-            (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74,
-            (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20,
-            (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
-            (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
-            (byte) 0x81, (byte) 0x00, (byte) 0xb5, (byte) 0xf6, (byte) 0x08, (byte) 0x0f,
-            (byte) 0xc4, (byte) 0x4d, (byte) 0xe4, (byte) 0x0d, (byte) 0x34, (byte) 0x1d,
-            (byte) 0xe2, (byte) 0x23, (byte) 0x18, (byte) 0x63, (byte) 0x03, (byte) 0xf7,
-            (byte) 0x14, (byte) 0x0e, (byte) 0x98, (byte) 0xcd, (byte) 0x45, (byte) 0x1f,
-            (byte) 0xfe, (byte) 0xfb, (byte) 0x09, (byte) 0x3f, (byte) 0x5d, (byte) 0x36,
-            (byte) 0x3b, (byte) 0x0f, (byte) 0xf9, (byte) 0x5e, (byte) 0x86, (byte) 0x56,
-            (byte) 0x64, (byte) 0xd7, (byte) 0x3f, (byte) 0xae, (byte) 0x33, (byte) 0x09,
-            (byte) 0xd3, (byte) 0xdd, (byte) 0x06, (byte) 0x17, (byte) 0x26, (byte) 0xdc,
-            (byte) 0xa2, (byte) 0x8c, (byte) 0x3c, (byte) 0x65, (byte) 0xed, (byte) 0x03,
-            (byte) 0x82, (byte) 0x78, (byte) 0x9b, (byte) 0xee, (byte) 0xe3, (byte) 0x98,
-            (byte) 0x58, (byte) 0xe1, (byte) 0xf1, (byte) 0xa0, (byte) 0x85, (byte) 0xae,
-            (byte) 0x63, (byte) 0x84, (byte) 0x41, (byte) 0x46, (byte) 0xa7, (byte) 0x4f,
-            (byte) 0xdc, (byte) 0xbb, (byte) 0x1c, (byte) 0x6e, (byte) 0xec, (byte) 0x7b,
-            (byte) 0xd5, (byte) 0xab, (byte) 0x3d, (byte) 0x6a, (byte) 0x05, (byte) 0x58,
-            (byte) 0x0f, (byte) 0x9b, (byte) 0x6a, (byte) 0x67, (byte) 0x4b, (byte) 0xe9,
-            (byte) 0x2a, (byte) 0x6d, (byte) 0x96, (byte) 0x11, (byte) 0x53, (byte) 0x95,
-            (byte) 0x78, (byte) 0xaa, (byte) 0xd1, (byte) 0x91, (byte) 0x4a, (byte) 0xf8,
-            (byte) 0x54, (byte) 0x52, (byte) 0x6d, (byte) 0xb9, (byte) 0xca, (byte) 0x74,
-            (byte) 0x81, (byte) 0xf8, (byte) 0x99, (byte) 0x64, (byte) 0xd1, (byte) 0x4f,
-            (byte) 0x01, (byte) 0x38, (byte) 0x4f, (byte) 0x08, (byte) 0x5c, (byte) 0x31,
-            (byte) 0xcb, (byte) 0x7c, (byte) 0x5c, (byte) 0x78, (byte) 0x5d, (byte) 0x47,
-            (byte) 0xd9, (byte) 0xf0, (byte) 0x1a, (byte) 0xeb, (byte) 0x02, (byte) 0x03,
-            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
-            (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
-            (byte) 0x5f, (byte) 0x5b, (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa,
-            (byte) 0xa1, (byte) 0x9f, (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1,
-            (byte) 0xbc, (byte) 0x20, (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4,
-            (byte) 0xfa, (byte) 0xe3, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
-            (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b, (byte) 0x5e,
-            (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f, (byte) 0x9e,
-            (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20, (byte) 0x72,
-            (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3, (byte) 0x30,
-            (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
-            (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
-            (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81,
-            (byte) 0x81, (byte) 0x00, (byte) 0xa1, (byte) 0x4a, (byte) 0xe6, (byte) 0xfc,
-            (byte) 0x7f, (byte) 0x17, (byte) 0xaa, (byte) 0x65, (byte) 0x4a, (byte) 0x34,
-            (byte) 0xde, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x4d, (byte) 0xa2,
-            (byte) 0xc2, (byte) 0x98, (byte) 0x02, (byte) 0x43, (byte) 0x6a, (byte) 0x0e,
-            (byte) 0x0b, (byte) 0x7f, (byte) 0xa4, (byte) 0x46, (byte) 0xaf, (byte) 0xa4,
-            (byte) 0x65, (byte) 0xa0, (byte) 0xdb, (byte) 0xf1, (byte) 0x5b, (byte) 0xd5,
-            (byte) 0x09, (byte) 0xbc, (byte) 0xee, (byte) 0x37, (byte) 0x51, (byte) 0x19,
-            (byte) 0x36, (byte) 0xc0, (byte) 0x90, (byte) 0xd3, (byte) 0x5f, (byte) 0xf3,
-            (byte) 0x4f, (byte) 0xb9, (byte) 0x08, (byte) 0x45, (byte) 0x0e, (byte) 0x01,
-            (byte) 0x8a, (byte) 0x95, (byte) 0xef, (byte) 0x92, (byte) 0x95, (byte) 0x33,
-            (byte) 0x78, (byte) 0xdd, (byte) 0x90, (byte) 0xbb, (byte) 0xf3, (byte) 0x06,
-            (byte) 0x75, (byte) 0xd0, (byte) 0x66, (byte) 0xe6, (byte) 0xd0, (byte) 0x18,
-            (byte) 0x6e, (byte) 0xeb, (byte) 0x1c, (byte) 0x52, (byte) 0xc3, (byte) 0x2e,
-            (byte) 0x57, (byte) 0x7d, (byte) 0xa9, (byte) 0x03, (byte) 0xdb, (byte) 0xf4,
-            (byte) 0x57, (byte) 0x5f, (byte) 0x6c, (byte) 0x7e, (byte) 0x00, (byte) 0x0d,
-            (byte) 0x8f, (byte) 0xe8, (byte) 0x91, (byte) 0xf7, (byte) 0xae, (byte) 0x24,
-            (byte) 0x35, (byte) 0x07, (byte) 0xb5, (byte) 0x48, (byte) 0x2d, (byte) 0x36,
-            (byte) 0x30, (byte) 0x5d, (byte) 0xe9, (byte) 0x49, (byte) 0x2d, (byte) 0xd1,
-            (byte) 0x5d, (byte) 0xc5, (byte) 0xf4, (byte) 0x33, (byte) 0x77, (byte) 0x3c,
-            (byte) 0x71, (byte) 0xad, (byte) 0x90, (byte) 0x65, (byte) 0xa9, (byte) 0xc1,
-            (byte) 0x0b, (byte) 0x5c, (byte) 0x62, (byte) 0x55, (byte) 0x50, (byte) 0x6f,
-            (byte) 0x9b, (byte) 0xc9, (byte) 0x0d, (byte) 0xee
-    };
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_EC_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x81, (byte) 0x87, (byte) 0x02, (byte) 0x01, (byte) 0x00,
-            (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
-            (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d,
-            (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x04, (byte) 0x6d, (byte) 0x30,
-            (byte) 0x6b, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x20,
-            (byte) 0x3a, (byte) 0x8a, (byte) 0x02, (byte) 0xdc, (byte) 0xde, (byte) 0x70,
-            (byte) 0x84, (byte) 0x45, (byte) 0x34, (byte) 0xaf, (byte) 0xbd, (byte) 0xd5,
-            (byte) 0x02, (byte) 0x17, (byte) 0x69, (byte) 0x90, (byte) 0x65, (byte) 0x1e,
-            (byte) 0x87, (byte) 0xf1, (byte) 0x3d, (byte) 0x17, (byte) 0xb6, (byte) 0xf4,
-            (byte) 0x31, (byte) 0x94, (byte) 0x86, (byte) 0x76, (byte) 0x55, (byte) 0xf7,
-            (byte) 0xcc, (byte) 0xba, (byte) 0xa1, (byte) 0x44, (byte) 0x03, (byte) 0x42,
-            (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7, (byte) 0x9b,
-            (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33, (byte) 0x14,
-            (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3, (byte) 0xcd,
-            (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d, (byte) 0xf3,
-            (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f, (byte) 0x79,
-            (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3, (byte) 0xd1,
-            (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf, (byte) 0x50,
-            (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22, (byte) 0xe6,
-            (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68, (byte) 0x3b,
-            (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77, (byte) 0x5e,
-            (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2, (byte) 0x38
-    };
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_EC_USER_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x51, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xba, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
-            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
-            (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-            (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13,
-            (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
-            (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74,
-            (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
-            (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
-            (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
-            (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
-            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
-            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x33,
-            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x31, (byte) 0x36,
-            (byte) 0x33, (byte) 0x30, (byte) 0x30, (byte) 0x38, (byte) 0x5a, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
-            (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x33, (byte) 0x30, (byte) 0x30,
-            (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
-            (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
-            (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
-            (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
-            (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
-            (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69,
-            (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20,
-            (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74,
-            (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x12,
-            (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65, (byte) 0x72,
-            (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70,
-            (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d,
-            (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02,
-            (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-            (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03,
-            (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7,
-            (byte) 0x9b, (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33,
-            (byte) 0x14, (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3,
-            (byte) 0xcd, (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d,
-            (byte) 0xf3, (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f,
-            (byte) 0x79, (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3,
-            (byte) 0xd1, (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf,
-            (byte) 0x50, (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22,
-            (byte) 0xe6, (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68,
-            (byte) 0x3b, (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77,
-            (byte) 0x5e, (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2,
-            (byte) 0x38, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
-            (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c,
-            (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01,
-            (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04,
-            (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65,
-            (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47,
-            (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74,
-            (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72,
-            (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61,
-            (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04,
-            (byte) 0x14, (byte) 0xd5, (byte) 0xc4, (byte) 0x72, (byte) 0xbd, (byte) 0xd2,
-            (byte) 0x4e, (byte) 0x90, (byte) 0x1b, (byte) 0x14, (byte) 0x32, (byte) 0xdb,
-            (byte) 0x03, (byte) 0xae, (byte) 0xfa, (byte) 0x27, (byte) 0x7d, (byte) 0x8d,
-            (byte) 0xe4, (byte) 0x80, (byte) 0x58, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18,
-            (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b,
-            (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f,
-            (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20,
-            (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0x43, (byte) 0x99, (byte) 0x9f, (byte) 0x67, (byte) 0x08,
-            (byte) 0x43, (byte) 0xd5, (byte) 0x6b, (byte) 0x6f, (byte) 0xd7, (byte) 0x05,
-            (byte) 0xd6, (byte) 0x75, (byte) 0x34, (byte) 0x30, (byte) 0xca, (byte) 0x20,
-            (byte) 0x47, (byte) 0x61, (byte) 0xa1, (byte) 0x89, (byte) 0xb6, (byte) 0xf1,
-            (byte) 0x49, (byte) 0x7b, (byte) 0xd9, (byte) 0xb9, (byte) 0xe8, (byte) 0x1e,
-            (byte) 0x29, (byte) 0x74, (byte) 0x0a, (byte) 0x67, (byte) 0xc0, (byte) 0x7d,
-            (byte) 0xb8, (byte) 0xe6, (byte) 0x39, (byte) 0xa8, (byte) 0x5e, (byte) 0xc3,
-            (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x6a, (byte) 0x1f, (byte) 0x1d,
-            (byte) 0xfc, (byte) 0x11, (byte) 0x59, (byte) 0x0b, (byte) 0xb9, (byte) 0xad,
-            (byte) 0x3a, (byte) 0x4e, (byte) 0x50, (byte) 0x0a, (byte) 0x61, (byte) 0xdb,
-            (byte) 0x75, (byte) 0x6b, (byte) 0xe5, (byte) 0x3f, (byte) 0x8d, (byte) 0xde,
-            (byte) 0x28, (byte) 0x68, (byte) 0xb1, (byte) 0x29, (byte) 0x9a, (byte) 0x18,
-            (byte) 0x8a, (byte) 0xfc, (byte) 0x3f, (byte) 0x13, (byte) 0x93, (byte) 0x29,
-            (byte) 0xed, (byte) 0x22, (byte) 0x7c, (byte) 0xb4, (byte) 0x50, (byte) 0xd5,
-            (byte) 0x4d, (byte) 0x32, (byte) 0x4d, (byte) 0x42, (byte) 0x2b, (byte) 0x29,
-            (byte) 0x97, (byte) 0x86, (byte) 0xc0, (byte) 0x01, (byte) 0x00, (byte) 0x25,
-            (byte) 0xf6, (byte) 0xd3, (byte) 0x2a, (byte) 0xd8, (byte) 0xda, (byte) 0x13,
-            (byte) 0x94, (byte) 0x12, (byte) 0x78, (byte) 0x14, (byte) 0x0b, (byte) 0x51,
-            (byte) 0xc0, (byte) 0x45, (byte) 0xb4, (byte) 0x02, (byte) 0x37, (byte) 0x98,
-            (byte) 0x42, (byte) 0x3c, (byte) 0xcb, (byte) 0x2e, (byte) 0xe4, (byte) 0x38,
-            (byte) 0x69, (byte) 0x1b, (byte) 0x72, (byte) 0xf0, (byte) 0xaa, (byte) 0x89,
-            (byte) 0x7e, (byte) 0xde, (byte) 0xb2
-    };
-
-    /**
-     * The amount of time to allow before and after expected time for variance
-     * in timing tests.
-     */
-    private static final long SLOP_TIME_MILLIS = 15000L;
-
-    @Override
-    protected void setUp() throws Exception {
-        mAndroidKeyStore = android.security.KeyStore.getInstance();
-
-        assertTrue(mAndroidKeyStore.reset());
-        assertFalse(mAndroidKeyStore.isUnlocked());
-
-        mKeyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-    }
-
-    private void setupPassword() {
-        assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
-        assertTrue(mAndroidKeyStore.isUnlocked());
-
-        assertEquals(0, mAndroidKeyStore.list("").length);
-    }
-
-    private void assertAliases(final String[] expectedAliases) throws KeyStoreException {
-        final Enumeration<String> aliases = mKeyStore.aliases();
-        int count = 0;
-
-        final Set<String> expectedSet = new HashSet<String>();
-        expectedSet.addAll(Arrays.asList(expectedAliases));
-
-        while (aliases.hasMoreElements()) {
-            count++;
-            final String alias = aliases.nextElement();
-            assertTrue("The alias should be in the expected set", expectedSet.contains(alias));
-            expectedSet.remove(alias);
-        }
-        assertTrue("The expected set and actual set should be exactly equal", expectedSet.isEmpty());
-        assertEquals("There should be the correct number of keystore entries",
-                expectedAliases.length, count);
-    }
-
-    public void testKeyStore_Aliases_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertAliases(new String[] {});
-
-        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
-                null));
-
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
-    }
-
-    public void testKeyStore_Aliases_NotInitialized_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        try {
-            mKeyStore.aliases();
-            fail("KeyStore should throw exception when not initialized");
-        } catch (KeyStoreException success) {
-        }
-    }
-
-    public void testKeyStore_ContainsAliases_PrivateAndCA_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertAliases(new String[] {});
-
-        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
-                null));
-
-        assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
-
-        assertFalse("Should not contain unadded certificate alias",
-                mKeyStore.containsAlias(TEST_ALIAS_3));
-    }
-
-    public void testKeyStore_ContainsAliases_CAOnly_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
-    }
-
-    public void testKeyStore_ContainsAliases_NonExistent_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_DeleteEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        // TEST_ALIAS_1
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        // TEST_ALIAS_2
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        // TEST_ALIAS_3
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
-
-        mKeyStore.deleteEntry(TEST_ALIAS_1);
-
-        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
-
-        mKeyStore.deleteEntry(TEST_ALIAS_3);
-
-        assertAliases(new String[] { TEST_ALIAS_2 });
-
-        mKeyStore.deleteEntry(TEST_ALIAS_2);
-
-        assertAliases(new String[] { });
-    }
-
-    public void testKeyStore_DeleteEntry_EmptyStore_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        // Should not throw when a non-existent entry is requested for delete.
-        mKeyStore.deleteEntry(TEST_ALIAS_1);
-    }
-
-    public void testKeyStore_DeleteEntry_NonExistent_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        // TEST_ALIAS_1
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        // Should not throw when a non-existent entry is requested for delete.
-        mKeyStore.deleteEntry(TEST_ALIAS_2);
-    }
-
-    public void testKeyStore_GetCertificate_Single_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        assertNull("Certificate should not exist in keystore",
-                mKeyStore.getCertificate(TEST_ALIAS_2));
-
-        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
-
-        assertNotNull("Retrieved certificate should not be null", retrieved);
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
-    }
-
-    public void testKeyStore_GetCertificate_NonExist_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertNull("Certificate should not exist in keystore",
-                mKeyStore.getCertificate(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_GetCertificateAlias_CAEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
-                mKeyStore.getCertificateAlias(actual));
-    }
-
-    public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-
-        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
-                mKeyStore.getCertificateAlias(actual));
-    }
-
-    public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        // Insert TrustedCertificateEntry with CA name
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        // Insert PrivateKeyEntry that uses the same CA
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
-                mKeyStore.getCertificateAlias(actual));
-    }
-
-    public void testKeyStore_GetCertificateAlias_NonExist_Empty_Encrypted_Failure()
-            throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        assertNull("Stored certificate alias should not be found",
-                mKeyStore.getCertificateAlias(actual));
-    }
-
-    public void testKeyStore_GetCertificateAlias_NonExist_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-
-        assertNull("Stored certificate alias should be found",
-                mKeyStore.getCertificateAlias(userCert));
-    }
-
-    public void testKeyStore_GetCertificateChain_SingleLength_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        Certificate[] expected = new Certificate[2];
-        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
-
-        assertNotNull("Returned certificate chain should not be null", actual);
-        assertEquals("Returned certificate chain should be correct size", expected.length,
-                actual.length);
-        assertEquals("First certificate should be user certificate", expected[0], actual[0]);
-        assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
-
-        // Negative test when keystore is populated.
-        assertNull("Stored certificate alias should not be found",
-                mKeyStore.getCertificateChain(TEST_ALIAS_2));
-    }
-
-    public void testKeyStore_GetCertificateChain_NonExist_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertNull("Stored certificate alias should not be found",
-                mKeyStore.getCertificateChain(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        Date now = new Date();
-        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
-
-        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
-        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
-
-        assertTrue("Time should be close to current time", actual.before(expectedBefore));
-        assertTrue("Time should be close to current time", actual.after(expectedAfter));
-    }
-
-    public void testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-
-        Date now = new Date();
-        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
-
-        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
-        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
-
-        assertTrue("Time should be close to current time", actual.before(expectedBefore));
-        assertTrue("Time should be close to current time", actual.after(expectedAfter));
-    }
-
-    public void testKeyStore_GetCreationDate_CAEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        Date now = new Date();
-        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
-        assertNotNull("Certificate should be found", actual);
-
-        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
-        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
-
-        assertTrue("Time should be close to current time", actual.before(expectedBefore));
-        assertTrue("Time should be close to current time", actual.after(expectedAfter));
-    }
-
-    public void testKeyStore_GetEntry_NullParams_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                FAKE_RSA_CA_1);
-    }
-
-    public void testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_EC_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                FAKE_EC_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_EC_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-
-        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-        assertPrivateKeyEntryEquals(keyEntry, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
-    }
-
-    public void testKeyStore_GetEntry_RSA_NullParams_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                FAKE_RSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-
-        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                FAKE_RSA_CA_1);
-    }
-
-    @SuppressWarnings("unchecked")
-    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, String keyType, byte[] key,
-            byte[] cert, byte[] ca) throws Exception {
-        KeyFactory keyFact = KeyFactory.getInstance(keyType);
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
-
-        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
-        Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
-
-        final Collection<Certificate> expectedChain;
-        if (ca != null) {
-            expectedChain = (Collection<Certificate>) certFact
-                    .generateCertificates(new ByteArrayInputStream(ca));
-        } else {
-            expectedChain = null;
-        }
-
-        assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
-    }
-
-    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
-            Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
-        if (expectedKey instanceof ECKey) {
-            assertEquals("Returned PrivateKey should be what we inserted",
-                    ((ECKey) expectedKey).getParams().getCurve(),
-                    ((ECKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve());
-        } else if (expectedKey instanceof RSAKey) {
-            assertEquals("Returned PrivateKey should be what we inserted",
-                    ((RSAKey) expectedKey).getModulus(),
-                    ((RSAKey) keyEntry.getPrivateKey()).getModulus());
-        }
-
-        assertEquals("Returned Certificate should be what we inserted", expectedCert,
-                keyEntry.getCertificate());
-
-        Certificate[] actualChain = keyEntry.getCertificateChain();
-
-        assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
-
-        if (expectedChain == null) {
-            assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
-        } else {
-            int i = 1;
-            final Iterator<Certificate> it = expectedChain.iterator();
-            while (it.hasNext()) {
-                assertEquals("CA chain certificate should equal what we put in", it.next(),
-                        actualChain[i++]);
-            }
-        }
-    }
-
-    public void testKeyStore_GetEntry_Nonexistent_NullParams_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertNull("A non-existent entry should return null",
-                mKeyStore.getEntry(TEST_ALIAS_1, null));
-    }
-
-    public void testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertNull("A non-existent entry should return null",
-                mKeyStore.getEntry(TEST_ALIAS_1, null));
-    }
-
-    public void testKeyStore_GetKey_NoPassword_Encrypted_Success() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
-        assertNotNull("Key should exist", key);
-
-        assertTrue("Should be a PrivateKey", key instanceof PrivateKey);
-        assertTrue("Should be a RSAKey", key instanceof RSAKey);
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-        assertEquals("Inserted key should be same as retrieved key",
-                ((RSAKey) expectedKey).getModulus(), ((RSAKey) key).getModulus());
-    }
-
-    public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-
-        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
-        assertNotNull("Key should exist", key);
-
-        assertTrue("Should be a PrivateKey", key instanceof PrivateKey);
-        assertTrue("Should be a RSAKey", key instanceof RSAKey);
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-        assertEquals("Inserted key should be same as retrieved key",
-                ((RSAKey) expectedKey).getModulus(), ((RSAKey) key).getModulus());
-    }
-
-    public void testKeyStore_GetKey_Certificate_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
-    }
-
-    public void testKeyStore_GetKey_NonExistent_Encrypted_Failure() throws Exception {
-        setupPassword();
-
-        mKeyStore.load(null, null);
-
-        assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
-    }
-
-    public void testKeyStore_GetProvider_Encrypted_Success() throws Exception {
-        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
-        setupPassword();
-        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
-    }
-
-    public void testKeyStore_GetType_Encrypted_Success() throws Exception {
-        assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType());
-        setupPassword();
-        assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType());
-    }
-
-    public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should return true for CA certificate",
-                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsCertificateEntry_PrivateKey_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertFalse("Should return false for PrivateKeyEntry",
-                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsCertificateEntry_NonExist_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertFalse("Should return false for non-existent entry",
-                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure() throws Exception {
-        mKeyStore.load(null, null);
-
-        assertFalse("Should return false for non-existent entry",
-                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsKeyEntry_PrivateKey_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsKeyEntry_CA_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_IsKeyEntry_NonExist_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertFalse("Should return false for non-existent entry",
-                mKeyStore.isKeyEntry(TEST_ALIAS_1));
-    }
-
-    public void testKeyStore_SetCertificate_CA_Encrypted_Success() throws Exception {
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
-
-        assertEquals("Retrieved certificate should be the same as the one inserted", actual,
-                retrieved);
-    }
-
-    public void testKeyStore_SetCertificate_CAExists_Overwrite_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        // TODO have separate FAKE_CA for second test
-        mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
-
-        assertAliases(new String[] { TEST_ALIAS_1 });
-    }
-
-    public void testKeyStore_SetCertificate_PrivateKeyExists_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        try {
-            mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
-            fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
-        } catch (KeyStoreException success) {
-        }
-    }
-
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Retrieved entry should exist", actualEntry);
-
-        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                actualEntry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
-    }
-
-    public void testKeyStore_SetEntry_PrivateKeyEntry_EC_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        KeyFactory keyFact = KeyFactory.getInstance("EC");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_EC_KEY_1));
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_CA_1));
-
-        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Retrieved entry should exist", actualEntry);
-
-        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                actualEntry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-        assertPrivateKeyEntryEquals(actual, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
-    }
-
-    public void testKeyStore_SetEntry_PrivateKeyEntry_RSA_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Retrieved entry should exist", actualEntry);
-
-        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                actualEntry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
-    }
-
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception {
-        mKeyStore.load(null, null);
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain);
-
-        try {
-            mKeyStore.setEntry(TEST_ALIAS_1, entry,
-                    new KeyStoreParameter.Builder(getContext())
-                    .setEncryptionRequired(true)
-                    .build());
-            fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized");
-        } catch (KeyStoreException expected) {
-        }
-
-        assertNull(mKeyStore.getEntry(TEST_ALIAS_1, null));
-    }
-
-    public void
-            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        // Start with PrivateKeyEntry
-        {
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-            final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-
-        // TODO make entirely new test vector for the overwrite
-        // Replace with PrivateKeyEntry
-        {
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-
-            final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-    }
-
-    public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        // Start with TrustedCertificateEntry
-        {
-            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
-                    actualEntry instanceof TrustedCertificateEntry);
-            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
-            assertEquals("Stored and retrieved certificates should be the same",
-                    expectedCertEntry.getTrustedCertificate(),
-                    actualCertEntry.getTrustedCertificate());
-        }
-
-        // Replace with PrivateKeyEntry
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-    }
-
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        // Start with PrivateKeyEntry
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            expectedChain[1] = caCert;
-
-            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-
-        // Replace with TrustedCertificateEntry
-        {
-            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
-                    actualEntry instanceof TrustedCertificateEntry);
-            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
-            assertEquals("Stored and retrieved certificates should be the same",
-                    expectedCertEntry.getTrustedCertificate(),
-                    actualCertEntry.getTrustedCertificate());
-        }
-    }
-
-    public
-            void
-            testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        // Start with PrivateKeyEntry
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            expectedChain[1] = caCert;
-
-            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-
-        // Replace with PrivateKeyEntry that has no chain
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] expectedChain = new Certificate[1];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-
-            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
-
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    null);
-        }
-    }
-
-    public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Encrypted_Success()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        // Insert TrustedCertificateEntry
-        {
-            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
-                    actualEntry instanceof TrustedCertificateEntry);
-            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
-            assertEquals("Stored and retrieved certificates should be the same",
-                    expectedCertEntry.getTrustedCertificate(),
-                    actualCertEntry.getTrustedCertificate());
-        }
-
-        // Replace with TrustedCertificateEntry of USER
-        {
-            final Certificate userCert = f
-                    .generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-
-            TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
-            mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
-                    actualEntry instanceof TrustedCertificateEntry);
-            TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
-            assertEquals("Stored and retrieved certificates should be the same",
-                    expectedUserEntry.getTrustedCertificate(),
-                    actualUserEntry.getTrustedCertificate());
-        }
-    }
-
-    public void testKeyStore_SetKeyEntry_ProtectedKey_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-        final Certificate[] chain = new Certificate[2];
-        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        chain[1] = caCert;
-
-        try {
-            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
-            fail("Should fail when a password is specified");
-        } catch (KeyStoreException success) {
-        }
-    }
-
-    public void testKeyStore_SetKeyEntry_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-        final Certificate[] chain = new Certificate[2];
-        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-        chain[1] = caCert;
-
-        mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
-
-        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Retrieved entry should exist", actualEntry);
-
-        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                actualEntry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
-    }
-
-    public void testKeyStore_SetKeyEntry_Replaced_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        final CertificateFactory f = CertificateFactory.getInstance("X.509");
-
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
-
-        // Insert initial key
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] chain = new Certificate[2];
-            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            chain[1] = caCert;
-
-            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-
-        // TODO make a separate key
-        // Replace key
-        {
-            KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
-            final Certificate[] chain = new Certificate[2];
-            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
-            chain[1] = caCert;
-
-            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
-
-            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-            assertNotNull("Retrieved entry should exist", actualEntry);
-
-            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
-                    actualEntry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
-
-            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
-                    FAKE_RSA_CA_1);
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private static X509Certificate generateCertificate(android.security.KeyStore keyStore,
-            String alias, BigInteger serialNumber, X500Principal subjectDN, Date notBefore,
-            Date notAfter) throws Exception {
-        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
-
-        KeyPair keyPair = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
-                keyStore, privateKeyAlias, KeyStore.UID_SELF);
-
-        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
-        certGen.setPublicKey(keyPair.getPublic());
-        certGen.setSerialNumber(serialNumber);
-        certGen.setSubjectDN(subjectDN);
-        certGen.setIssuerDN(subjectDN);
-        certGen.setNotBefore(notBefore);
-        certGen.setNotAfter(notAfter);
-        certGen.setSignatureAlgorithm("sha1WithRSA");
-
-        final X509Certificate cert = certGen.generate(keyPair.getPrivate());
-
-        return cert;
-    }
-
-    public void testKeyStore_SetKeyEntry_ReplacedChain_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        // Create key #1
-        {
-            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
-            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
-
-            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
-
-            assertTrue(key instanceof PrivateKey);
-
-            PrivateKey expectedKey = (PrivateKey) key;
-
-            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
-                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
-
-            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                    expectedCert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-
-            assertTrue(entry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
-        }
-
-        // Replace key #1 with new chain
-        {
-            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
-
-            assertTrue(key instanceof PrivateKey);
-
-            PrivateKey expectedKey = (PrivateKey) key;
-
-            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
-                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
-
-            mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
-                    new Certificate[] { expectedCert });
-
-            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-
-            assertTrue(entry instanceof PrivateKeyEntry);
-
-            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
-        }
-    }
-
-    public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Encrypted_Failure()
-            throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        // Create key #1
-        {
-            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
-            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
-
-            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
-                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
-
-            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                    cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        }
-
-        // Create key #2
-        {
-            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
-            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
-
-            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
-                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
-
-            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_2,
-                    cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        }
-
-        // Replace key #1 with key #2
-        {
-            Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);
-
-            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
-                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
-
-            try {
-                mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
-                fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
-            } catch (KeyStoreException success) {
-            }
-        }
-    }
-
-    public void testKeyStore_SetKeyEntry_ReplacedChain_UnencryptedToEncrypted_Failure()
-            throws Exception {
-        mKeyStore.load(null, null);
-
-        // Create key #1
-        {
-            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
-            assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
-                    android.security.KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
-                    android.security.KeyStore.FLAG_NONE, null));
-
-            X509Certificate cert =
-                    generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1, TEST_DN_1,
-                            NOW, NOW_PLUS_10_YEARS);
-
-            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                    cert.getEncoded(), android.security.KeyStore.UID_SELF,
-                    android.security.KeyStore.FLAG_NONE));
-        }
-
-        // Replace with one that requires encryption
-        {
-            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-
-            try {
-                mKeyStore.setEntry(TEST_ALIAS_1, entry,
-                        new KeyStoreParameter.Builder(getContext())
-                                .setEncryptionRequired(true)
-                                .build());
-                fail("Should not allow setting of Entry without unlocked keystore");
-            } catch (KeyStoreException success) {
-            }
-
-            assertTrue(mAndroidKeyStore.onUserPasswordChanged("1111"));
-            assertTrue(mAndroidKeyStore.isUnlocked());
-
-            mKeyStore.setEntry(TEST_ALIAS_1, entry,
-                    new KeyStoreParameter.Builder(getContext())
-                            .setEncryptionRequired(true)
-                            .build());
-        }
-    }
-
-    public void testKeyStore_Size_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
-        assertAliases(new String[] { TEST_ALIAS_1 });
-
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-
-        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
-        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
-
-        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
-                KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
-                null));
-
-        assertEquals("The keystore size should match expected", 3, mKeyStore.size());
-        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
-
-        assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));
-
-        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
-        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
-
-        assertTrue(mAndroidKeyStore.delete(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
-
-        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
-        assertAliases(new String[] { TEST_ALIAS_2 });
-    }
-
-    public void testKeyStore_Store_LoadStoreParam_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        try {
-            mKeyStore.store(null);
-            fail("Should throw UnsupportedOperationException when trying to store");
-        } catch (UnsupportedOperationException success) {
-        }
-    }
-
-    public void testKeyStore_Load_InputStreamSupplied_Encrypted_Failure() throws Exception {
-        byte[] buf = "FAKE KEYSTORE".getBytes();
-        ByteArrayInputStream is = new ByteArrayInputStream(buf);
-
-        try {
-            mKeyStore.load(is, null);
-            fail("Should throw IllegalArgumentException when InputStream is supplied");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyStore_Load_PasswordSupplied_Encrypted_Failure() throws Exception {
-        try {
-            mKeyStore.load(null, "password".toCharArray());
-            fail("Should throw IllegalArgumentException when password is supplied");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyStore_Store_OutputStream_Encrypted_Failure() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        OutputStream sink = new ByteArrayOutputStream();
-        try {
-            mKeyStore.store(sink, null);
-            fail("Should throw UnsupportedOperationException when trying to store");
-        } catch (UnsupportedOperationException success) {
-        }
-
-        try {
-            mKeyStore.store(sink, "blah".toCharArray());
-            fail("Should throw UnsupportedOperationException when trying to store");
-        } catch (UnsupportedOperationException success) {
-        }
-    }
-
-    private void setupKey() throws Exception {
-        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
-        assertTrue(mAndroidKeyStore
-                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
-                        KeyStore.FLAG_ENCRYPTED, null));
-
-        X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
-                TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
-
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
-                cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-    }
-
-    public void testKeyStore_KeyOperations_Wrap_Encrypted_Success() throws Exception {
-        setupPassword();
-        mKeyStore.load(null, null);
-
-        setupKey();
-
-        // Test key usage
-        Entry e = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull(e);
-        assertTrue(e instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry privEntry = (PrivateKeyEntry) e;
-        PrivateKey privKey = privEntry.getPrivateKey();
-        assertNotNull(privKey);
-
-        PublicKey pubKey = privEntry.getCertificate().getPublicKey();
-
-        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
-        c.init(Cipher.WRAP_MODE, pubKey);
-
-        byte[] expectedKey = new byte[] {
-                0x00, 0x05, (byte) 0xAA, (byte) 0x0A5, (byte) 0xFF, 0x55, 0x0A
-        };
-
-        SecretKey expectedSecret = new SecretKeySpec(expectedKey, "AES");
-
-        byte[] wrappedExpected = c.wrap(expectedSecret);
-
-        c.init(Cipher.UNWRAP_MODE, privKey);
-        SecretKey actualSecret = (SecretKey) c.unwrap(wrappedExpected, "AES", Cipher.SECRET_KEY);
-
-        assertEquals(Arrays.toString(expectedSecret.getEncoded()),
-                Arrays.toString(actualSecret.getEncoded()));
-    }
-}
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index 05fec5e..0835cad 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -19,7 +19,7 @@
 # Build the legacy-test library
 # =============================
 # This contains the junit.framework and android.test classes that were in
-# Android API level 25.
+# Android API level 25 excluding those from android.test.runner.
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -31,10 +31,13 @@
 
 # Build the legacy-android-test library
 # =============================
-# This contains the android.test classes that were in Android API level 25.
+# This contains the android.test classes that were in Android API level 25,
+# including those from android.test.runner.
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src/android)
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src/android) \
+    $(call all-java-files-under, ../test-runner/src/android)
 LOCAL_MODULE := legacy-android-test
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart framework junit
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 9f2d129..acf8883 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -237,6 +237,7 @@
     },
 
     export_include_dirs: ["."],
+    export_shared_lib_headers: ["libRScpp"],
 }
 
 cc_library {
@@ -258,7 +259,6 @@
     srcs: [
         "debug/nullegl.cpp",
     ],
-    export_include_dirs: ["."],
 }
 
 cc_defaults {
@@ -334,6 +334,7 @@
         "tests/unit/TestUtilsTests.cpp",
         "tests/unit/TextDropShadowCacheTests.cpp",
         "tests/unit/TextureCacheTests.cpp",
+	"tests/unit/TypefaceTests.cpp",
         "tests/unit/VectorDrawableTests.cpp",
     ],
 }
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 34c7934..e91c08d 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -110,6 +110,7 @@
         } vertices;
 
         int elementCount;
+        int vertexCount; // only used for meshes (for glDrawRangeElements)
         TextureVertex mappedVertices[4];
     } mesh;
 
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 931a55a..2e9a6e8 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -199,6 +199,7 @@
             alphaVertex ? kAlphaVertexStride : kVertexStride };
     mOutGlop->mesh.elementCount = indices
                 ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();
+    mOutGlop->mesh.vertexCount = vertexBuffer.getVertexCount(); // used for glDrawRangeElements()
     return *this;
 }
 
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index d64804e..4ef0f4b 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -27,6 +27,7 @@
 #include <GLES2/gl2.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <gui/Surface.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/OpenGLReadback.h b/libs/hwui/OpenGLReadback.h
index c9222cf..403f2e3 100644
--- a/libs/hwui/OpenGLReadback.h
+++ b/libs/hwui/OpenGLReadback.h
@@ -18,6 +18,9 @@
 
 #include "Readback.h"
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index b763953..7cf4262 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -20,10 +20,10 @@
 #include "Rect.h"
 
 #include <SkBitmap.h>
-#include <gui/Surface.h>
 
 namespace android {
 class GraphicBuffer;
+class Surface;
 namespace uirenderer {
 
 // Keep in sync with PixelCopy.java codes
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index b113626..d8207b1 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -474,7 +474,6 @@
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
     if (isHardware()) {
-        ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation");
         outBitmap->allocPixels(info());
         uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
         return;
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 4fb4b533..f66bb04 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -36,28 +36,33 @@
 #include <minikin/FontFamily.h>
 #include <minikin/Layout.h>
 #include <utils/Log.h>
+#include <utils/MathUtils.h>
 
 namespace android {
 
-// This indicates that the passed information should be resolved by OS/2 table.
-// This value must be the same as the android.graphics.Typeface$Builder.RESOLVE_BY_FONT_TABLE.
-constexpr int RESOLVE_BY_FONT_TABLE = -1;
+static SkTypeface::Style computeSkiaStyle(int weight, bool italic) {
+    // This bold detection comes from SkTypeface.h
+    if (weight >= SkFontStyle::kSemiBold_Weight) {
+        return italic ? SkTypeface::kBoldItalic : SkTypeface::kBold;
+    } else {
+        return italic ? SkTypeface::kItalic : SkTypeface::kNormal;
+    }
+}
 
-// Resolve the 1..10 weight based on base weight and bold flag
-static void resolveStyle(Typeface* typeface) {
+static minikin::FontStyle computeMinikinStyle(int weight, bool italic) {
     // TODO: Better to use raw base weight value for font selection instead of dividing by 100.
-    int weight = (typeface->fBaseWeight + 50) / 100;
-    if (typeface->fSkiaStyle & SkTypeface::kBold) {
-        weight += 3;
+    const int minikinWeight = uirenderer::MathUtils::clamp((weight + 50) / 100, 1, 10);
+    return minikin::FontStyle(minikinWeight, italic);
+}
+
+// Resolve the relative weight from the baseWeight and target style.
+static minikin::FontStyle computeRelativeStyle(int baseWeight, SkTypeface::Style relativeStyle) {
+    int weight = baseWeight;
+    if ((relativeStyle & SkTypeface::kBold) != 0) {
+        weight += 300;
     }
-    if (weight > 10) {
-        weight = 10;
-    }
-    if (weight < 1) {
-        weight = 1;
-    }
-    bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0;
-    typeface->fStyle = minikin::FontStyle(weight, italic);
+    bool italic = (relativeStyle & SkTypeface::kItalic) != 0;
+    return computeMinikinStyle(weight, italic);
 }
 
 Typeface* gDefaultTypeface = NULL;
@@ -67,26 +72,26 @@
     return src == nullptr ? gDefaultTypeface : src;
 }
 
-Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
+Typeface* Typeface::createRelative(Typeface* src, SkTypeface::Style style) {
     Typeface* resolvedFace = Typeface::resolveDefault(src);
     Typeface* result = new Typeface;
     if (result != nullptr) {
         result->fFontCollection = resolvedFace->fFontCollection;
-        result->fSkiaStyle = style;
         result->fBaseWeight = resolvedFace->fBaseWeight;
-        resolveStyle(result);
+        result->fSkiaStyle = style;
+        result->fStyle = computeRelativeStyle(result->fBaseWeight, style);
     }
     return result;
 }
 
-Typeface* Typeface::createFromTypefaceWithStyle(Typeface* base, int weight, bool italic) {
+Typeface* Typeface::createAbsolute(Typeface* base, int weight, bool italic) {
     Typeface* resolvedFace = Typeface::resolveDefault(base);
     Typeface* result = new Typeface();
     if (result != nullptr) {
         result->fFontCollection = resolvedFace->fFontCollection;
-        result->fBaseWeight = weight;
-        result->fStyle = minikin::FontStyle(weight / 100, italic);
-        result->fSkiaStyle = resolvedFace->fSkiaStyle;
+        result->fBaseWeight = resolvedFace->fBaseWeight;
+        result->fSkiaStyle = computeSkiaStyle(weight, italic);
+        result->fStyle = computeMinikinStyle(weight, italic);
     }
     return result;
 }
@@ -103,21 +108,23 @@
             // So we will reuse the same collection with incrementing reference count.
             result->fFontCollection = resolvedFace->fFontCollection;
         }
-        result->fSkiaStyle = resolvedFace->fSkiaStyle;
+        // Do not update styles.
+        // TODO: We may want to update base weight if the 'wght' is specified.
         result->fBaseWeight = resolvedFace->fBaseWeight;
-        resolveStyle(result);
+        result->fSkiaStyle = resolvedFace->fSkiaStyle;
+        result->fStyle = resolvedFace->fStyle;
     }
     return result;
 }
 
-Typeface* Typeface::createWeightAlias(Typeface* src, int weight) {
+Typeface* Typeface::createWithDifferentBaseWeight(Typeface* src, int weight) {
     Typeface* resolvedFace = Typeface::resolveDefault(src);
     Typeface* result = new Typeface;
     if (result != nullptr) {
         result->fFontCollection = resolvedFace->fFontCollection;
-        result->fSkiaStyle = resolvedFace->fSkiaStyle;
         result->fBaseWeight = weight;
-        resolveStyle(result);
+        result->fSkiaStyle = resolvedFace->fSkiaStyle;
+        result->fStyle = computeRelativeStyle(weight, result->fSkiaStyle);
     }
     return result;
 }
@@ -160,14 +167,8 @@
     }
 
     result->fBaseWeight = weight;
-    // This bold detection comes from SkTypefae.h
-    const bool isBold = weight >= SkFontStyle::kSemiBold_Weight;
-    const bool isItalic = italic == 1;
-    // TODO: remove fSkiaStyle
-    result->fSkiaStyle = isBold ?
-            (isItalic ? SkTypeface::kBoldItalic : SkTypeface::kBold) :
-            (isItalic ? SkTypeface::kItalic : SkTypeface::kNormal);
-    resolveStyle(result);
+    result->fSkiaStyle = computeSkiaStyle(weight, italic);
+    result->fStyle = computeMinikinStyle(weight, italic);
     return result;
 }
 
@@ -197,7 +198,7 @@
     Typeface* hwTypeface = new Typeface();
     hwTypeface->fFontCollection = collection;
     hwTypeface->fSkiaStyle = SkTypeface::kNormal;
-    hwTypeface->fBaseWeight = SkFontStyle::kSemiBold_Weight;
+    hwTypeface->fBaseWeight = SkFontStyle::kNormal_Weight;
     hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */);
 
     Typeface::setDefault(hwTypeface);
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index e35a7b4..db0b2cd 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -27,28 +27,53 @@
 
 namespace android {
 
-struct ANDROID_API Typeface {
-    std::shared_ptr<minikin::FontCollection> fFontCollection;
+// This indicates that the weight or italic information should be resolved by OS/2 table.
+// This value must be the same as the android.graphics.Typeface$Builder.RESOLVE_BY_FONT_TABLE.
+constexpr int RESOLVE_BY_FONT_TABLE = -1;
 
-    // style used for constructing and querying Typeface objects
-    SkTypeface::Style fSkiaStyle;
-    // base weight in CSS-style units, 100..900
-    int fBaseWeight;
+struct ANDROID_API Typeface {
+ public:
+    std::shared_ptr<minikin::FontCollection> fFontCollection;
 
     // resolved style actually used for rendering
     minikin::FontStyle fStyle;
 
+    // style used for constructing and querying Typeface objects
+    SkTypeface::Style fSkiaStyle;
+
     static Typeface* resolveDefault(Typeface* src);
 
-    static Typeface* createFromTypeface(Typeface* src, SkTypeface::Style style);
-
-    static Typeface* createFromTypefaceWithStyle(Typeface* base, int weight, bool italic);
+    // The following three functions create new Typeface from an existing Typeface with a different
+    // style. There is a base weight concept which is used for calculating relative style from an
+    // existing Typeface.
+    // The createRelative method creates a new Typeface with a style relative to the base Typeface.
+    // For example, if the base Typeface has a base weight of 400 and the desired style is bold, the
+    // resulting Typeface renders the text with a weight of 700. This function doesn't change the
+    // base weight, so even if you create a new Typeface from the bold Typeface specifying bold on
+    // it again, the text is still rendered with a weight of 700.
+    // You can create another base weight Typeface from an existing Typeface with
+    // createWithDifferentBaseWeight. The Typeface created with this function renders the text with
+    // a specified base weight.
+    // The createAbsolute method creates a new Typeface ignoring the base weight.
+    // Here is an example:
+    //   Typeface* base = resolveDefault(nullptr);  // Usually this has a weight of 400.
+    //   Typeface* bold = createRelative(base, Bold);  // Rendered with a weight of 700.
+    //   Typeface* bold2 = createRelative(bold, Bold); // Rendered with a weight of 700.
+    //
+    //   Typeface* boldBase = createWithDifferentBaseWeight(base, 700);  // With a weight of 700.
+    //   Typeface* boldBold = createRelative(boldBase, Bold);  // Rendered with a weight of 1000.
+    //
+    //   Typeface* lightBase = createWithDifferentBaseWeight(base, 300);  // With a weight of 300.
+    //   Typeface* lightBold = createRelative(lightBase, Bold);  // Rendered with a weight of 600.
+    //
+    //   Typeface* black = createAbsolute(base, 900, false);  // Rendered with a weight of 900.
+    static Typeface* createWithDifferentBaseWeight(Typeface* src, int baseweight);
+    static Typeface* createRelative(Typeface* src, SkTypeface::Style desiredStyle);
+    static Typeface* createAbsolute(Typeface* base, int weight, bool italic);
 
     static Typeface* createFromTypefaceWithVariation(Typeface* src,
             const std::vector<minikin::FontVariation>& variations);
 
-    static Typeface* createWeightAlias(Typeface* src, int baseweight);
-
     static Typeface* createFromFamilies(
             std::vector<std::shared_ptr<minikin::FontFamily>>&& families,
             int weight, int italic);
@@ -57,6 +82,10 @@
 
     // Sets roboto font as the default typeface for testing purpose.
     static void setRobotoTypefaceForTest();
+ private:
+    // base weight in CSS-style units, 1..1000
+    int fBaseWeight;
+
 };
 
 }
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index c8833d2..8b737bb 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -413,18 +413,28 @@
         const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position);
         while (elementsCount > 0) {
             GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
+            GLsizei vertexCount = (drawCount / 6) * 4;
             meshState().bindPositionVertexPointer(vertexData, vertices.stride);
             if (vertices.attribFlags & VertexAttribFlags::TextureCoord) {
                 meshState().bindTexCoordsVertexPointer(
                         vertexData + kMeshTextureOffset, vertices.stride);
             }
 
-            glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr);
+            if (mCaches->extensions().getMajorGlVersion() >= 3) {
+                glDrawRangeElements(mesh.primitiveMode, 0, vertexCount-1, drawCount, GL_UNSIGNED_SHORT, nullptr);
+            } else {
+                glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr);
+            }
             elementsCount -= drawCount;
-            vertexData += (drawCount / 6) * 4 * vertices.stride;
+            vertexData += vertexCount * vertices.stride;
         }
     } else if (indices.bufferObject || indices.indices) {
-        glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+        if (mCaches->extensions().getMajorGlVersion() >= 3) {
+            // use glDrawRangeElements to reduce CPU overhead (otherwise the driver has to determine the min/max index values)
+            glDrawRangeElements(mesh.primitiveMode, 0, mesh.vertexCount-1, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+        } else {
+            glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+        }
     } else {
         glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount);
     }
diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
index 9a3b81c..c46592c 100644
--- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
@@ -118,7 +118,7 @@
     layerPaint.setAlpha(128);
     OffscreenBuffer* buffer = nullptr; // no providing a buffer, should hit rect fallback case
     LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer);
-    testUnmergedGlopDispatch(renderThread, &op, [&renderThread] (const Glop& glop) {
+    testUnmergedGlopDispatch(renderThread, &op, [] (const Glop& glop) {
         ADD_FAILURE() << "Nothing should happen";
     }, 0);
 }
diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp
new file mode 100644
index 0000000..c90b6f0
--- /dev/null
+++ b/libs/hwui/tests/unit/TypefaceTests.cpp
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+
+#include "SkFontMgr.h"
+#include "SkStream.h"
+
+#include "hwui/MinikinSkia.h"
+#include "hwui/Typeface.h"
+
+using namespace android;
+
+namespace {
+
+constexpr char kRobotoRegular[] = "/system/fonts/Roboto-Regular.ttf";
+constexpr char kRobotoBold[] = "/system/fonts/Roboto-Bold.ttf";
+constexpr char kRobotoItalic[] = "/system/fonts/Roboto-Italic.ttf";
+constexpr char kRobotoBoldItalic[] = "/system/fonts/Roboto-BoldItalic.ttf";
+
+void unmap(const void* ptr, void* context) {
+    void* p = const_cast<void*>(ptr);
+    size_t len = reinterpret_cast<size_t>(context);
+    munmap(p, len);
+}
+
+std::shared_ptr<minikin::FontFamily> buildFamily(const char* fileName) {
+    int fd = open(fileName, O_RDONLY);
+    LOG_ALWAYS_FATAL_IF(fd == -1, "Failed to open file %s", fileName);
+    struct stat st = {};
+    LOG_ALWAYS_FATAL_IF(fstat(fd, &st) == -1, "Failed to stat file %s", fileName);
+    void* data = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    sk_sp<SkData> skData =
+            SkData::MakeWithProc(data, st.st_size, unmap, reinterpret_cast<void*>(st.st_size));
+    std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(skData));
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
+    sk_sp<SkTypeface> typeface(fm->createFromStream(fontData.release()));
+    LOG_ALWAYS_FATAL_IF(typeface == nullptr, "Failed to make typeface from %s", fileName);
+    std::shared_ptr<minikin::MinikinFont> font = std::make_shared<MinikinFontSkia>(
+            std::move(typeface), data, st.st_size, 0, std::vector<minikin::FontVariation>());
+    return std::make_shared<minikin::FontFamily>(
+            std::vector<minikin::Font>({ minikin::Font(std::move(font), minikin::FontStyle()) }));
+}
+
+std::vector<std::shared_ptr<minikin::FontFamily>> makeSingleFamlyVector(const char* fileName) {
+    return std::vector<std::shared_ptr<minikin::FontFamily>>({ buildFamily(fileName) });
+}
+
+TEST(TypefaceTest, resolveDefault_and_setDefaultTest) {
+    std::unique_ptr<Typeface> regular(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(regular.get(), Typeface::resolveDefault(regular.get()));
+
+    Typeface* old = Typeface::resolveDefault(nullptr);  // Keep the original to restore it later.
+    ASSERT_NE(nullptr, old);
+
+    Typeface::setDefault(regular.get());
+    EXPECT_EQ(regular.get(), Typeface::resolveDefault(nullptr));
+
+    Typeface::setDefault(old);  // Restore to the original.
+}
+
+TEST(TypefaceTest, createWithDifferentBaseWeight) {
+    std::unique_ptr<Typeface> bold(Typeface::createWithDifferentBaseWeight(nullptr, 700));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, bold->fSkiaStyle);
+
+    std::unique_ptr<Typeface> light(Typeface::createWithDifferentBaseWeight(nullptr, 300));
+    EXPECT_EQ(3, light->fStyle.getWeight());
+    EXPECT_FALSE(light->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, light->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_fromRegular) {
+    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(nullptr, SkTypeface::kNormal));
+    EXPECT_EQ(4, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(nullptr, SkTypeface::kBold));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.ITALIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(nullptr, SkTypeface::kItalic));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface> boldItalic(
+            Typeface::createRelative(nullptr, SkTypeface::kBoldItalic));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_BoldBase) {
+    std::unique_ptr<Typeface> base(Typeface::createWithDifferentBaseWeight(nullptr, 700));
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
+    EXPECT_EQ(7, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
+    EXPECT_EQ(10, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.ITALIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
+    EXPECT_EQ(7, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-bold"), Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface>
+            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
+    EXPECT_EQ(10, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_LightBase) {
+    std::unique_ptr<Typeface> base(Typeface::createWithDifferentBaseWeight(nullptr, 300));
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
+    EXPECT_EQ(3, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
+    EXPECT_EQ(6, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.ITLIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
+    EXPECT_EQ(3, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create("sans-serif-light"), Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface>
+            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
+    EXPECT_EQ(6, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_fromBoldStyled) {
+    std::unique_ptr<Typeface> base(Typeface::createRelative(nullptr, SkTypeface::kBold));
+
+    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
+    EXPECT_EQ(4, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.ITALIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
+    EXPECT_EQ(4, normal->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.BOLD), Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface>
+            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_fromItalicStyled) {
+    std::unique_ptr<Typeface> base(Typeface::createRelative(nullptr, SkTypeface::kItalic));
+
+    // In Java,
+    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
+    EXPECT_EQ(4, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java, Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java,
+    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.ITALIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // Typeface.create(Typeface.create(Typeface.DEFAULT, Typeface.ITALIC), Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface>
+            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createRelativeTest_fromSpecifiedStyled) {
+    std::unique_ptr<Typeface> base(Typeface::createAbsolute(nullptr, 400, false));
+
+    // In Java,
+    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
+    //     .setWeight(700).setItalic(false).build();
+    // Typeface.create(typeface, Typeface.NORMAL);
+    std::unique_ptr<Typeface> normal(Typeface::createRelative(base.get(), SkTypeface::kNormal));
+    EXPECT_EQ(4, normal->fStyle.getWeight());
+    EXPECT_FALSE(normal->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, normal->fSkiaStyle);
+
+    // In Java,
+    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
+    //     .setWeight(700).setItalic(false).build();
+    // Typeface.create(typeface, Typeface.BOLD);
+    std::unique_ptr<Typeface> bold(Typeface::createRelative(base.get(), SkTypeface::kBold));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java,
+    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
+    //     .setWeight(700).setItalic(false).build();
+    // Typeface.create(typeface, Typeface.ITALIC);
+    std::unique_ptr<Typeface> italic(Typeface::createRelative(base.get(), SkTypeface::kItalic));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // Typeface typeface = new Typeface.Builder(invalid).setFallback("sans-serif")
+    //     .setWeight(700).setItalic(false).build();
+    // Typeface.create(typeface, Typeface.BOLD_ITALIC);
+    std::unique_ptr<Typeface>
+            boldItalic(Typeface::createRelative(base.get(), SkTypeface::kBoldItalic));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createAbsolute) {
+    // In Java,
+    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(400).setItalic(false)
+    //     .build();
+    std::unique_ptr<Typeface> regular(Typeface::createAbsolute(nullptr, 400, false));
+    EXPECT_EQ(4, regular->fStyle.getWeight());
+    EXPECT_FALSE(regular->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(700).setItalic(false)
+    //     .build();
+    std::unique_ptr<Typeface> bold(Typeface::createAbsolute(nullptr, 700, false));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(400).setItalic(true)
+    //     .build();
+    std::unique_ptr<Typeface> italic(Typeface::createAbsolute(nullptr, 400, true));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(700).setItalic(true)
+    //     .build();
+    std::unique_ptr<Typeface> boldItalic(Typeface::createAbsolute(nullptr, 700, true));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBoldItalic, boldItalic->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder(invalid).setFallback("sans-serif").setWeight(1100).setItalic(true)
+    //     .build();
+    std::unique_ptr<Typeface> over1000(Typeface::createAbsolute(nullptr, 1100, false));
+    EXPECT_EQ(10, over1000->fStyle.getWeight());
+    EXPECT_FALSE(over1000->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, over1000->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createFromFamilies_Single) {
+    // In Java, new Typeface.Builder("Roboto-Regular.ttf").setWeight(400).setItalic(false).build();
+    std::unique_ptr<Typeface> regular(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular), 400, false));
+    EXPECT_EQ(4, regular->fStyle.getWeight());
+    EXPECT_FALSE(regular->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);
+
+    // In Java, new Typeface.Builder("Roboto-Bold.ttf").setWeight(700).setItalic(false).build();
+    std::unique_ptr<Typeface> bold(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold), 700, false));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, new Typeface.Builder("Roboto-Italic.ttf").setWeight(400).setItalic(true).build();
+    std::unique_ptr<Typeface> italic(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoItalic), 400, true));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder("Roboto-BoldItalic.ttf").setWeight(700).setItalic(true).build();
+    std::unique_ptr<Typeface> boldItalic(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBoldItalic), 700, true));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java,
+    // new Typeface.Builder("Roboto-BoldItalic.ttf").setWeight(1100).setItalic(false).build();
+    std::unique_ptr<Typeface> over1000(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold), 1100, false));
+    EXPECT_EQ(10, over1000->fStyle.getWeight());
+    EXPECT_FALSE(over1000->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, over1000->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createFromFamilies_Single_resolveByTable) {
+    // In Java, new Typeface.Builder("Roboto-Regular.ttf").build();
+    std::unique_ptr<Typeface> regular(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoRegular),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(4, regular->fStyle.getWeight());
+    EXPECT_FALSE(regular->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kNormal, regular->fSkiaStyle);
+
+    // In Java, new Typeface.Builder("Roboto-Bold.ttf").build();
+    std::unique_ptr<Typeface> bold(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBold),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(7, bold->fStyle.getWeight());
+    EXPECT_FALSE(bold->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kBold, bold->fSkiaStyle);
+
+    // In Java, new Typeface.Builder("Roboto-Italic.ttf").build();
+    std::unique_ptr<Typeface> italic(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoItalic),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(4, italic->fStyle.getWeight());
+    EXPECT_TRUE(italic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+
+    // In Java, new Typeface.Builder("Roboto-BoldItalic.ttf").build();
+    std::unique_ptr<Typeface> boldItalic(
+            Typeface::createFromFamilies(makeSingleFamlyVector(kRobotoBoldItalic),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(7, boldItalic->fStyle.getWeight());
+    EXPECT_TRUE(boldItalic->fStyle.getItalic());
+    EXPECT_EQ(SkTypeface::kItalic, italic->fSkiaStyle);
+}
+
+TEST(TypefaceTest, createFromFamilies_Family) {
+    std::vector<std::shared_ptr<minikin::FontFamily>> families = {
+            buildFamily(kRobotoRegular), buildFamily(kRobotoBold), buildFamily(kRobotoItalic),
+            buildFamily(kRobotoBoldItalic)
+    };
+    std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies(std::move(families),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(4, typeface->fStyle.getWeight());
+    EXPECT_FALSE(typeface->fStyle.getItalic());
+}
+
+TEST(TypefaceTest, createFromFamilies_Family_withoutRegular) {
+    std::vector<std::shared_ptr<minikin::FontFamily>> families = {
+            buildFamily(kRobotoBold), buildFamily(kRobotoItalic), buildFamily(kRobotoBoldItalic)
+    };
+    std::unique_ptr<Typeface> typeface(Typeface::createFromFamilies(std::move(families),
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+    EXPECT_EQ(7, typeface->fStyle.getWeight());
+    EXPECT_FALSE(typeface->fStyle.getItalic());
+}
+
+}  // namespace
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index dd66649..9bd93aa 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -35,6 +35,7 @@
 import com.android.internal.app.IAppOpsService;
 
 import java.lang.IllegalArgumentException;
+import java.lang.ref.WeakReference;
 import java.util.Objects;
 
 /**
@@ -45,11 +46,11 @@
  */
 public abstract class PlayerBase {
 
-    private final static String TAG = "PlayerBase";
-    private final static boolean DEBUG = false;
+    private static final String TAG = "PlayerBase";
+    private static final boolean DEBUG = false;
     private static IAudioService sService; //lazy initialization, use getService()
     /** Debug app ops */
-    protected static final boolean DEBUG_APP_OPS = Log.isLoggable(TAG + ".AO", Log.DEBUG);
+    private static final boolean DEBUG_APP_OPS = false;
 
     // parameters of the player that affect AppOps
     protected AudioAttributes mAttributes;
@@ -94,19 +95,9 @@
         IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
         mAppOps = IAppOpsService.Stub.asInterface(b);
         // initialize mHasAppOpsPlayAudio
-        synchronized (mLock) {
-            updateAppOpsPlayAudio_sync();
-        }
+        updateAppOpsPlayAudio();
         // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
-        mAppOpsCallback = new IAppOpsCallback.Stub() {
-            public void opChanged(int op, int uid, String packageName) {
-                synchronized (mLock) {
-                    if (op == AppOpsManager.OP_PLAY_AUDIO) {
-                        updateAppOpsPlayAudio_sync();
-                    }
-                }
-            }
-        };
+        mAppOpsCallback = new IAppOpsCallbackWrapper(this);
         try {
             mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
                     ActivityThread.currentPackageName(), mAppOpsCallback);
@@ -114,10 +105,8 @@
             mHasAppOpsPlayAudio = false;
         }
         try {
-            if (mIPlayer == null) {
-                throw new IllegalStateException("Cannot register a player with a null mIPlayer");
-            }
-            newPiid = getService().trackPlayer(new PlayerIdCard(mImplType, mAttributes, mIPlayer));
+            newPiid = getService().trackPlayer(
+                    new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this)));
         } catch (RemoteException e) {
             Log.e(TAG, "Error talking to audio service, player will not be tracked", e);
         }
@@ -259,6 +248,12 @@
         }
     }
 
+    private void updateAppOpsPlayAudio() {
+        synchronized (mLock) {
+            updateAppOpsPlayAudio_sync();
+        }
+    }
+
     /**
      * To be called whenever a condition that might affect audibility of this player is updated.
      * Must be called synchronized on mLock.
@@ -406,47 +401,95 @@
     abstract void playerStop();
 
     //=====================================================================
+    private static class IAppOpsCallbackWrapper extends IAppOpsCallback.Stub {
+        private final WeakReference<PlayerBase> mWeakPB;
+
+        public IAppOpsCallbackWrapper(PlayerBase pb) {
+            mWeakPB = new WeakReference<PlayerBase>(pb);
+        }
+
+        @Override
+        public void opChanged(int op, int uid, String packageName) {
+            if (op == AppOpsManager.OP_PLAY_AUDIO) {
+                if (DEBUG_APP_OPS) { Log.v(TAG, "opChanged: op=PLAY_AUDIO pack=" + packageName); }
+                final PlayerBase pb = mWeakPB.get();
+                if (pb != null) {
+                    pb.updateAppOpsPlayAudio();
+                }
+            }
+        }
+    }
+
+    //=====================================================================
     /**
-     * Implementation of IPlayer for all subclasses of PlayerBase
+     * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase
+     * that doesn't keep a strong reference on PlayerBase
      */
-    private IPlayer mIPlayer = new IPlayer.Stub() {
+    private static class IPlayerWrapper extends IPlayer.Stub {
+        private final WeakReference<PlayerBase> mWeakPB;
+
+        public IPlayerWrapper(PlayerBase pb) {
+            mWeakPB = new WeakReference<PlayerBase>(pb);
+        }
+
         @Override
         public void start() {
-            playerStart();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStart();
+            }
         }
 
         @Override
         public void pause() {
-            playerPause();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerPause();
+            }
         }
 
         @Override
         public void stop() {
-            playerStop();
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStop();
+            }
         }
 
         @Override
         public void setVolume(float vol) {
-            baseSetVolume(vol, vol);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetVolume(vol, vol);
+            }
         }
 
         @Override
         public void setPan(float pan) {
-            baseSetPan(pan);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetPan(pan);
+            }
         }
 
         @Override
         public void setStartDelayMs(int delayMs) {
-            baseSetStartDelayMs(delayMs);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetStartDelayMs(delayMs);
+            }
         }
 
         @Override
         public void applyVolumeShaper(
                 @NonNull VolumeShaper.Configuration configuration,
                 @NonNull VolumeShaper.Operation operation) {
-            /* void */ playerApplyVolumeShaper(configuration, operation);
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerApplyVolumeShaper(configuration, operation);
+            }
         }
-    };
+    }
 
     //=====================================================================
     /**
@@ -455,8 +498,8 @@
     public static class PlayerIdCard implements Parcelable {
         public final int mPlayerType;
 
-        public final static int AUDIO_ATTRIBUTES_NONE = 0;
-        public final static int AUDIO_ATTRIBUTES_DEFINED = 1;
+        public static final int AUDIO_ATTRIBUTES_NONE = 0;
+        public static final int AUDIO_ATTRIBUTES_DEFINED = 1;
         public final AudioAttributes mAttributes;
         public final IPlayer mIPlayer;
 
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index e774c71..3eb9d52 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -943,7 +943,8 @@
 
         // Sanity-check: are we actually being asked to install an audio file?
         final String mimeType = mContext.getContentResolver().getType(fileUri);
-        if(mimeType == null || !mimeType.startsWith("audio/")) {
+        if(mimeType == null ||
+                !(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) {
             throw new IllegalArgumentException("Ringtone file must have MIME type \"audio/*\"."
                     + " Given file has MIME type \"" + mimeType + "\"");
         }
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
index d5296ae..c091c84 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -137,7 +137,7 @@
         }
 
         /**
-         * Gets the raw audio that triggered the keyphrase.
+         * Gets the raw audio that triggered the detector.
          * This may be null if the trigger audio isn't available.
          * If non-null, the format of the audio can be obtained by calling
          * {@link #getCaptureAudioFormat()}.
@@ -154,6 +154,24 @@
         }
 
         /**
+         * Gets the opaque data passed from the detection engine for the event.
+         * This may be null if it was not populated by the engine, or if the data is known to
+         * contain the trigger audio.
+         *
+         * @see #getTriggerAudio
+         *
+         * @hide
+         */
+        @Nullable
+        public byte[] getData() {
+            if (!mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
          * Gets the session ID to start a capture from the DSP.
          * This may be null if streaming capture isn't possible.
          * If non-null, the format of the audio that can be captured can be
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 4496a82..e7da20b 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1453,7 +1453,8 @@
         /**
          * The release date of this TV program.
          *
-         * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
+         * <p>The value should be in one of the following formats:
+         * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601).
          *
          * <p>Type: TEXT
          */
@@ -1624,7 +1625,12 @@
     /** Column definitions for the TV channels table. */
     public static final class Channels implements BaseTvColumns {
 
-        /** The content:// style URI for this table. */
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
                 + PATH_CHANNEL);
 
@@ -2423,7 +2429,12 @@
      */
     public static final class Programs implements BaseTvColumns, ProgramColumns {
 
-        /** The content:// style URI for this table. */
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
                 + PATH_PROGRAM);
 
@@ -2737,7 +2748,12 @@
      */
     public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns {
 
-        /** The content:// style URI for this table. */
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
                 + PATH_RECORDED_PROGRAM);
 
@@ -2858,7 +2874,12 @@
     public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns,
         PreviewProgramColumns {
 
-        /** The content:// style URI for this table. */
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
                 + PATH_PREVIEW_PROGRAM);
 
@@ -2905,7 +2926,12 @@
     public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns,
         PreviewProgramColumns {
 
-        /** The content:// style URI for this table. */
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
                 + PATH_WATCH_NEXT_PROGRAM);
 
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 87092d0..5f1cf16 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -30,9 +30,9 @@
 #include "SoundPool.h"
 #include "SoundPoolThread.h"
 #include <media/AudioPolicyHelper.h>
-#include <ndk/NdkMediaCodec.h>
-#include <ndk/NdkMediaExtractor.h>
-#include <ndk/NdkMediaFormat.h>
+#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaExtractor.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android
 {
diff --git a/native/android/Android.bp b/native/android/Android.bp
index eacda93..452adc0 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -19,3 +19,71 @@
     first_version: "9",
     unversioned_until: "current",
 }
+
+cc_defaults {
+    name: "libandroid_defaults",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+}
+
+cc_library_shared {
+    name: "libandroid",
+    defaults: ["libandroid_defaults"],
+
+    srcs: [
+        "asset_manager.cpp",
+        "choreographer.cpp",
+        "configuration.cpp",
+        "hardware_buffer_jni.cpp",
+        "input.cpp",
+        "looper.cpp",
+        "native_activity.cpp",
+        "native_window_jni.cpp",
+        "net.c",
+        "obb.cpp",
+        "sensor.cpp",
+        "sharedmem.cpp",
+        "storage_manager.cpp",
+        "trace.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libandroidfw",
+        "libinput",
+        "libutils",
+        "libbinder",
+        "libui",
+        "libgui",
+        "libsensor",
+        "libandroid_runtime",
+        "libnetd_client",
+    ],
+
+    static_libs: [
+        "libstorage",
+        "libarect",
+    ],
+
+    whole_static_libs: ["libnativewindow"],
+
+    export_static_lib_headers: ["libarect"],
+
+    include_dirs: ["bionic/libc/dns/include"],
+}
+
+// Network library.
+cc_library_shared {
+    name: "libandroid_net",
+    defaults: ["libandroid_defaults"],
+    srcs: ["net.c"],
+
+    shared_libs: ["libnetd_client"],
+
+    include_dirs: ["bionic/libc/dns/include"],
+}
diff --git a/native/android/Android.mk b/native/android/Android.mk
deleted file mode 100644
index 6e15331..0000000
--- a/native/android/Android.mk
+++ /dev/null
@@ -1,77 +0,0 @@
-BASE_PATH := $(call my-dir)
-LOCAL_PATH:= $(call my-dir)
-
-common_cflags := -Wall -Werror -Wunused -Wunreachable-code
-
-include $(CLEAR_VARS)
-
-# our source files
-#
-LOCAL_SRC_FILES:= \
-    asset_manager.cpp \
-    choreographer.cpp \
-    configuration.cpp \
-    hardware_buffer_jni.cpp \
-    input.cpp \
-    looper.cpp \
-    native_activity.cpp \
-    native_window_jni.cpp \
-    net.c \
-    obb.cpp \
-    sensor.cpp \
-    sharedmem.cpp \
-    storage_manager.cpp \
-    trace.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libcutils \
-    libandroidfw \
-    libinput \
-    libutils \
-    libbinder \
-    libui \
-    libgui \
-    libsensor \
-    libandroid_runtime \
-    libnetd_client \
-
-LOCAL_STATIC_LIBRARIES := \
-    libstorage \
-    libarect \
-
-LOCAL_WHOLE_STATIC_LIBRARIES := \
-    libnativewindow
-
-LOCAL_C_INCLUDES += \
-    frameworks/base/native/include \
-    frameworks/base/core/jni/android \
-    bionic/libc/dns/include \
-    system/netd/include \
-
-LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := \
-    libarect \
-    libnativewindow \
-
-LOCAL_MODULE := libandroid
-
-LOCAL_CFLAGS += $(common_cflags)
-
-include $(BUILD_SHARED_LIBRARY)
-
-# Network library.
-include $(CLEAR_VARS)
-LOCAL_MODULE := libandroid_net
-LOCAL_CFLAGS := $(common_cflags)
-LOCAL_SRC_FILES:= \
-    net.c \
-
-LOCAL_SHARED_LIBRARIES := \
-    libnetd_client \
-
-LOCAL_C_INCLUDES += \
-    frameworks/base/native/include \
-    bionic/libc/dns/include \
-    system/netd/include \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
index de870e0..53d77c37 100644
--- a/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bs/strings.xml
@@ -19,7 +19,7 @@
     <string name="backup_confirm_title" msgid="827563724209303345">"Napraviti potpunu rezervnu kopiju"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Izvrši potpuno obnavljanje"</string>
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zatraženo je pravljenje potpune rezervne kopije svih podataka na povezani računar. Da li želite da dozvolite to?\n\nPrekinite radnju ukoliko to niste sami zatražili."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi rezervnu kopiju mojih podataka"</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Napravi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nemoj napraviti rezervnu kopiju"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"Sa povezanog računara je upućen zahtjev za potpuno obnavljanje svih podataka. Želite li to dozvoliti?\n\nUkoliko niste uputili zahtjev za obnavljanje, prekinite radnju. Ovim će zamijeniti svi podaci koji su trenutno na uređaju!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovi moje podatke"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
index 4c13c73..3ad7c96 100644
--- a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
@@ -26,7 +26,7 @@
     <string name="deny_restore_button_label" msgid="1724367334453104378">"אל תשחזר"</string>
     <string name="current_password_text" msgid="8268189555578298067">"הזן את סיסמת הגיבוי הנוכחית למטה:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"הזן את סיסמת ההצפנה של המכשיר שלך בהמשך."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"הזן את סיסמת ההצפנה של המכשיר שלך בהמשך. הסיסמה תשמש גם להצפנת ארכיון הגיבוי."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"עליך להזין את סיסמת ההצפנה של המכשיר שלך בהמשך. הסיסמה תשמש גם להצפנת ארכיון הגיבוי."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"הזן סיסמה שתשמש להצפנה של נתוני הגיבוי המלא. אם תשאיר שדה זה ריק, ייעשה שימוש בסיסמת הגיבוי הנוכחית שלך:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"אם אתה רוצה להצפין את נתוני הגיבוי המלא, הזן סיסמה בהמשך:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"מכיוון שהמכשיר מוצפן, אתה נדרש להצפין את הגיבוי. הזן סיסמה בהמשך:"</string>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index b958c28..f844cc1 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -17,6 +17,7 @@
 package com.android.externalstorage;
 
 import android.annotation.Nullable;
+import android.app.usage.StorageStatsManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.UriPermission;
@@ -49,10 +50,12 @@
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.UUID;
 
 public class ExternalStorageProvider extends FileSystemProvider {
     private static final String TAG = "ExternalStorage";
@@ -79,6 +82,7 @@
     private static class RootInfo {
         public String rootId;
         public String volumeId;
+        public UUID storageUuid;
         public int flags;
         public String title;
         public String docId;
@@ -124,6 +128,7 @@
 
             final String rootId;
             final String title;
+            final UUID storageUuid;
             if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
                 // We currently only support a single emulated volume mounted at
                 // a time, and it's always considered the primary
@@ -142,17 +147,20 @@
                     title = !TextUtils.isEmpty(deviceName)
                             ? deviceName
                             : getContext().getString(R.string.root_internal_storage);
+                    storageUuid = StorageManager.UUID_DEFAULT;
                 } else {
                     // This should cover all other storage devices, like an SD card
                     // or USB OTG drive plugged in. Using getBestVolumeDescription()
                     // will give us a nice string like "Samsung SD card" or "SanDisk USB drive"
                     final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
                     title = mStorageManager.getBestVolumeDescription(privateVol);
+                    storageUuid = StorageManager.convert(privateVol.fsUuid);
                 }
             } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC
                     && volume.getMountUserId() == userId) {
                 rootId = volume.getFsUuid();
                 title = mStorageManager.getBestVolumeDescription(volume);
+                storageUuid = null;
             } else {
                 // Unsupported volume; ignore
                 continue;
@@ -172,6 +180,7 @@
 
             root.rootId = rootId;
             root.volumeId = volume.id;
+            root.storageUuid = storageUuid;
             root.flags = Root.FLAG_LOCAL_ONLY
                     | Root.FLAG_SUPPORTS_SEARCH
                     | Root.FLAG_SUPPORTS_IS_CHILD;
@@ -385,8 +394,22 @@
                 row.add(Root.COLUMN_FLAGS, root.flags);
                 row.add(Root.COLUMN_TITLE, root.title);
                 row.add(Root.COLUMN_DOCUMENT_ID, root.docId);
-                row.add(Root.COLUMN_AVAILABLE_BYTES,
-                        root.reportAvailableBytes ? root.path.getUsableSpace() : -1);
+
+                long availableBytes = -1;
+                if (root.reportAvailableBytes) {
+                    if (root.storageUuid != null) {
+                        try {
+                            availableBytes = getContext()
+                                    .getSystemService(StorageStatsManager.class)
+                                    .getFreeBytes(root.storageUuid);
+                        } catch (IOException e) {
+                            Log.w(TAG, e);
+                        }
+                    } else {
+                        availableBytes = root.path.getUsableSpace();
+                    }
+                }
+                row.add(Root.COLUMN_AVAILABLE_BYTES, availableBytes);
             }
         }
         return result;
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
index 1e536f1..9a31f74 100644
--- a/packages/PrintSpooler/res/values-in/strings.xml
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -32,7 +32,7 @@
     <string name="template_page_range" msgid="428638530038286328">"Rentang dari <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"misalnya 1—5,8,11—13"</string>
     <string name="print_preview" msgid="8010217796057763343">"Pratinjau cetak"</string>
-    <string name="install_for_print_preview" msgid="6366303997385509332">"Pasang penampil PDF untuk pratinjau"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instal penampil PDF untuk pratinjau"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"Aplikasi pencetakan mogok"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"Membuat tugas pencetakan"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"Simpan sebagai PDF"</string>
@@ -76,8 +76,8 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Layanan dinonaktifkan"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Semua layanan"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="other">Pasang untuk menemukan <xliff:g id="COUNT_1">%1$s</xliff:g> printer</item>
-      <item quantity="one">Pasang untuk menemukan <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item>
+      <item quantity="other">Instal untuk menemukan <xliff:g id="COUNT_1">%1$s</xliff:g> printer</item>
+      <item quantity="one">Instal untuk menemukan <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/layout/preference_two_target.xml b/packages/SettingsLib/res/layout/preference_two_target.xml
index 8f30d87..4c2583c 100644
--- a/packages/SettingsLib/res/layout/preference_two_target.xml
+++ b/packages/SettingsLib/res/layout/preference_two_target.xml
@@ -37,7 +37,7 @@
             android:id="@+id/icon_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:minWidth="60dp"
+            android:minWidth="56dp"
             android:orientation="horizontal"
             android:paddingEnd="12dp"
             android:paddingTop="4dp"
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 21b4fbce..841c96e 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -82,12 +82,12 @@
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ভুল পিন বা পাস কী দেওয়ার কারণে <xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যুক্ত করা যায়নি।"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> এর সঙ্গে যোগাযোগ করতে পারবেন না।"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"যুক্ত করা <xliff:g id="DEVICE_NAME">%1$s</xliff:g> প্রত্যাখ্যান করেছে।"</string>
-    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wifi বন্ধ৷"</string>
-    <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wifi এর সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
-    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wifi এ একটি দণ্ড৷"</string>
-    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wifi এ দুইটি দণ্ড৷"</string>
-    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"Wifi এ তিনটি দণ্ড৷"</string>
-    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"Wifi এ সম্পূর্ণ সিগন্যাল৷"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"ওয়াই ফাই বন্ধ৷"</string>
+    <string name="accessibility_no_wifi" msgid="8834610636137374508">"ওয়াই ফাই এর সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
+    <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"ওয়াই ফাই এ একটি দণ্ড৷"</string>
+    <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"ওয়াই ফাই এ দুইটি দণ্ড৷"</string>
+    <string name="accessibility_wifi_three_bars" msgid="8134185644861380311">"ওয়াই ফাই এ তিনটি দণ্ড৷"</string>
+    <string name="accessibility_wifi_signal_full" msgid="7061045677694702">"ওয়াই ফাই এ সম্পূর্ণ সিগন্যাল৷"</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"সরানো অ্যাপ্লিকেশানগুলি"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"সরানো অ্যাপ্লিকেশানগুলি এবং ব্যবহারকারীগণ"</string>
@@ -171,7 +171,7 @@
     <string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string>
     <string name="wifi_aggressive_handover" msgid="5309131983693661320">"ওয়াই-ফাই থেকে মোবাইলে তৎপর হস্তান্তর"</string>
-    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা Wifi রোম স্ক্যানকে অনুমতি দিন"</string>
+    <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা ওয়াই ফাই রোম স্ক্যানকে অনুমতি দিন"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string>
     <string name="bluetooth_enable_inband_ringing" msgid="3291686366721786740">"ইন-ব্যান্ড রিং করা সক্ষম করুন"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index e0b3e36..2bfb4a5 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -245,7 +245,7 @@
     <item msgid="7899496259191969307">"Najviše 4 procesa"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
-    <item msgid="488237561639712799">"Puni se"</item>
+    <item msgid="488237561639712799">"Punjenje"</item>
     <item msgid="5220695614993094977">"MTP (protokol za prijenos sadržaja medija)"</item>
     <item msgid="2086000968159047375">"PTP (protokol za prijenos slika)"</item>
     <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 6d755ea..451a1ff 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -114,8 +114,8 @@
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Postavlja glas za dati jezik za izgovoreni tekst"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Poslušajte primjer"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Reproduciraj kratku demonstraciju sintetiziranja govora"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliraj glasovne podatke"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instalirajte glasovne podatke potrebne za sintetiziranje govora"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliranje glasovnih podataka"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instaliranje glasovnih podataka potrebnih za sintetiziranje govora"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Ovaj program za sintetiziranje govora u mogućnosti je da prikuplja sav tekst koji se izgovara, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Program omogućava aplikacija <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Da li želite koristiti ovaj program za sintetiziranje govora?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva aktivnu mrežnu vezu za pretvaranje teksta u govor."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ovo je primjer sinteze govora"</string>
@@ -319,7 +319,7 @@
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može uticati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Preostalo je otprilike još <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Do potpune napunjenosti preostalo je <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Imate još <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - imate još <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -327,7 +327,7 @@
     <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
-    <string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
+    <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 13dde32f..39d4a76 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -31,9 +31,9 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fuera de rango"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"No se establecerá conexión automáticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"No se ha detectado acceso a Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Guardadas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Guardada por <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectada automáticamente a través de %1$s"</string>
-    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectada automáticamente a través de un proveedor de valoración de red"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automáticamente a través de un proveedor de valoración de redes"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string>
     <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conexión sin Internet"</string>
@@ -315,7 +315,7 @@
     <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"Deuteronomalía (rojo-verde)"</string>
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Protanomalía (rojo-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Tritanomalía (azul-amarillo)"</string>
-    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección del color"</string>
+    <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"Tiempo restante aproximado: <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index cc52862..36d19ef 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -93,7 +93,7 @@
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Eemaldatud rakendused ja kasutajad"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB jagamine"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Kantav tööpunkt"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetoothi jagamine"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Jagamine Bluetoothiga"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Jagamine"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"Jagam. ja kant. kuumkoht"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Kõik töörakendused"</string>
@@ -114,8 +114,8 @@
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Määrab räägitud teksti keelespetsiifilise hääle"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Kuulake näidet"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Esita lühike kõnesünteesi demo"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"Installi hääleandmed"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"Installi kõnesünteesi jaoks vajalikud hääleandmed"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"Häälandmete installimine"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"Installige kõnesünteesi jaoks vajalikud häälandmed"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"See kõnesünteesimootor võib koguda kogu kõneldud teksti, sh isiklikke andmeid, nagu paroolid ja krediitkaardinumbrid. Selle aluseks on mootor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Kas lubada kõnesünteesimootori kasutamine?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Selle keele puhul on kõnesünteesi väljundi jaoks vaja toimivat võrguühendust."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"See on kõnesünteesi näide"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 155f1c5..5d29ec0 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Hors de portée"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Reconnexion automatique impossible"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Enregistré par <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Enregistré par : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement via un fournisseur d\'évaluation de l\'état du réseau"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 8b57734..929332f 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -324,7 +324,7 @@
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante aproximado: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> (tempo restante: <xliff:g id="TIME">%2$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata que cargue por completo"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata completar a carga"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g>)"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 14ba223..8dd85c3 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Ընդգրկույթից դուրս է"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Չի միանա ավտոմատ"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Ինտերնետ կապ չկա"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Պահել է հետևյալ օգտատերը՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Պահել է՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Ավտոմատ կերպով կապակցվել է %1$s-ի միջոցով"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Ավտոմատ կերպով միացել է ցանցի վարկանիշի ծառայության մատակարարի միջոցով"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Կապակցված է %1$s-ի միջոցով"</string>
@@ -216,7 +216,7 @@
     <string name="enable_terminal_title" msgid="95572094356054120">"Տեղային տերմինալ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Միացնել տերմինալային հավելվածը, որն առաջարկում է մուտք տեղային խեցի"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ստուգում"</string>
-    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"Կարգավորել HDCP ստուգման վարքագիծը"</string>
+    <string name="hdcp_checking_dialog_title" msgid="5141305530923283">"HDCP-ի ստուգման կարգը"</string>
     <string name="debug_debugging_category" msgid="6781250159513471316">"Վրիպազերծում"</string>
     <string name="debug_app" msgid="8349591734751384446">"Ընտրել վրիպազերծման հավելվածը"</string>
     <string name="debug_app_not_set" msgid="718752499586403499">"Վրիպազերծման ծրագիրը կարգավորված չէ"</string>
@@ -294,7 +294,7 @@
     <item msgid="8280754435979370728">"Բնական գույներ"</item>
     <item msgid="5363960654009010371">"Թվային բովանդակության համար հարմարեցված գույներ"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="1317817863508274533">"Միացրած հավելվածներ"</string>
+    <string name="inactive_apps_title" msgid="1317817863508274533">"Անգործուն հավելվածներ"</string>
     <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Ակտիվ չէ: Հպեք՝ փոխելու համար:"</string>
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"Ակտիվ է: Հպեք՝ փոխելու համար:"</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Աշխատեցվող ծառայություններ"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 0b19a7b..7f02a6a 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -45,7 +45,7 @@
     <item msgid="7698638434317271902">"Diputus dari <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
     <item msgid="197508606402264311">"Sambungan terputus"</item>
     <item msgid="8578370891960825148">"Gagal"</item>
-    <item msgid="5660739516542454527">"Dicekal"</item>
+    <item msgid="5660739516542454527">"Diblokir"</item>
     <item msgid="1805837518286731242">"Menghindari sambungan buruk untuk sementara"</item>
   </string-array>
   <string-array name="hdcp_checking_titles">
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 733e2cb..e0157bc 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -114,8 +114,8 @@
     <string name="tts_default_lang_summary" msgid="5219362163902707785">"Menyetel suara spesifik bahasa untuk teks lisan"</string>
     <string name="tts_play_example_title" msgid="7094780383253097230">"Dengarkan contoh"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Putar demonstrasi singkat dari sintesis suara"</string>
-    <string name="tts_install_data_title" msgid="4264378440508149986">"Pasang data suara"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"Pasang data suara yang dibutuhkan untuk sintesis suara"</string>
+    <string name="tts_install_data_title" msgid="4264378440508149986">"Instal data suara"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"Instal data suara yang dibutuhkan untuk sintesis suara"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Mesin sintesis suara ini mungkin dapat mengumpulkan semua teks yang akan diucapkan, termasuk di antaranya data pribadi seperti sandi dan nomor kartu kredit. Berasal dari <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> aplikasi. Gunakan metode masukan ini?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Bahasa ini perlu sambungan jaringan yang bekerja untuk keluaran text-to-speech."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ini adalah contoh sintesis suara"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 14b8e37..0ebe77e5 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -101,7 +101,7 @@
     <string name="unknown" msgid="1592123443519355854">"Sconosciuta"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Utente: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
     <string name="launch_defaults_some" msgid="313159469856372621">"Alcune opzioni predefinite impostate"</string>
-    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna applicazione predefinita impostata"</string>
+    <string name="launch_defaults_none" msgid="4241129108140034876">"Nessuna app predefinita impostata"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Impostazioni di sintesi vocale"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Output sintesi vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocità voce"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index d299ec6..917415c 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -91,7 +91,7 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"ប្រព័ន្ធ​ប្រតិបត្តិការ Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"កម្មវិធី​ដែល​បាន​លុប"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"បាន​លុប​កម្មវិធី និង​អ្នកប្រើ"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"ការ​ភ្ជាប់​យូអេសប៊ី"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"ការ​ភ្ជាប់តាម USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ហតស្ពត​ចល័ត"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ការ​ភ្ជាប់ប៊្លូធូស"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ការ​ភ្ជាប់"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 16ba336..2da43f0 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -248,7 +248,7 @@
     <item msgid="488237561639712799">"Се полни"</item>
     <item msgid="5220695614993094977">"МТП (Протокол за трансфер на медиуми)"</item>
     <item msgid="2086000968159047375">"ПТП (Протокол за трансфер на слика)"</item>
-    <item msgid="7398830860950841822">"РНДИС (УСБ за етернет)"</item>
+    <item msgid="7398830860950841822">"РНДИС (USB за етернет)"</item>
     <item msgid="1718924214939774352">"Аудиоизвор"</item>
     <item msgid="8126315616613006284">"МИДИ"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index f38ef5d..88b3675 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -55,7 +55,7 @@
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Користи за споделување контакти"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Споделување конекција на интернет"</string>
     <string name="bluetooth_profile_map" msgid="5465271250454324383">"Порака за пристап"</string>
-    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до СИМ"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Пристап до SIM"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="2221025895896419505">"Користи висококвалитетно аудио: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="5860996587596508755">"Користи висококвалитетно аудио"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Поврзан со аудио на медиуми"</string>
@@ -69,7 +69,7 @@
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1561383706411975199">"Споделување локална конекција на интернет со уред"</string>
     <string name="bluetooth_pan_profile_summary_use_for" msgid="5664884523822068653">"Користи за пристап на интернет"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Користи за карта"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Користете се пристап до СИМ"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Користете се пристап до SIM"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Користи за аудио на медиуми"</string>
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Користи за аудио на телефон"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Користи за пренос на датотеки"</string>
@@ -91,7 +91,7 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Оперативен систем Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Отстранети апликации"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Отстранети апликации и корисници"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Поврзување со УСБ"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Поврзување со USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Преносл. точка на пристап"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Поврзување со Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Поврзување"</string>
@@ -153,7 +153,7 @@
     <string name="apn_settings_not_available" msgid="7873729032165324000">"Поставките за името на пристапната точка не се достапни за овој корисник"</string>
     <string name="enable_adb" msgid="7982306934419797485">"Отстранување грешки на USB"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"Режим на отстранување грешки кога е поврзано USB"</string>
-    <string name="clear_adb_keys" msgid="4038889221503122743">"Отповикај овластувања за отстранување грешки од УСБ"</string>
+    <string name="clear_adb_keys" msgid="4038889221503122743">"Отповикај овластувања за отстранување грешки од USB"</string>
     <string name="bugreport_in_power" msgid="7923901846375587241">"Кратенка за извештај за грешка"</string>
     <string name="bugreport_in_power_summary" msgid="1778455732762984579">"Прикажи копче во менито за вклучување за да се направи извештај за грешка"</string>
     <string name="keep_screen_on" msgid="1146389631208760344">"Остани во активен режим"</string>
@@ -198,18 +198,18 @@
     <string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"Кога веќе не го следиме постојаниот дневник, мора да ги избришеме податоците на дневникот што се наоѓаат на вашиот уред."</string>
     <string name="select_logpersist_title" msgid="7530031344550073166">"Зачувувај податоци на дневникот"</string>
     <string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Изберете привремена меморија на евиденција што ќе се користи постојано на уредот"</string>
-    <string name="select_usb_configuration_title" msgid="2649938511506971843">"Изберете конфигурација за УСБ"</string>
-    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Изберете конфигурација за УСБ"</string>
+    <string name="select_usb_configuration_title" msgid="2649938511506971843">"Изберете конфигурација за USB"</string>
+    <string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Изберете конфигурација за USB"</string>
     <string name="allow_mock_location" msgid="2787962564578664888">"Овозможи лажни локации"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Овозможи лажни локации"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Овозможете проверка на атрибутот на приказот"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Секогаш држи го активен мобилниот интернет, дури и при активно Wi-Fi (за брзо префрлување мрежа)."</string>
-    <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на УСБ?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на УСБ е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од УСБ од сите претходно овластени компјутери?"</string>
+    <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на USB?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Дозволи подесувања за развој?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Овие подесувања се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Потврди апликации преку УСБ"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Потврди апликации преку USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Провери апликации инсталирани преку ADB/ADT за штетно однесување."</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Ја оневозможува карактеристиката за апсолутна јачина на звук преку Bluetooth во случај кога ќе настанат проблеми со далечинските уреди, како на пр., неприфатливо силен звук или недоволна контрола."</string>
     <string name="bluetooth_enable_inband_ringing_summary" msgid="2787866074741784975">"Дозволи мелодиите на телефонот да се пуштаат на Bluetooth слушалките"</string>
@@ -250,8 +250,8 @@
     <string name="disable_overlays_summary" msgid="3578941133710758592">"Секогаш користи GPU за составување екран"</string>
     <string name="simulate_color_space" msgid="6745847141353345872">"Симулирај простор на бои"</string>
     <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Овозможи траги на OpenGL"</string>
-    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Исклучи УСБ-пренасочување"</string>
-    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Исклучи автоматско пренасочување до УСБ-аудиоуреди"</string>
+    <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Исклучи USB-пренасочување"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Исклучи автоматско пренасочување до USB-аудиоуреди"</string>
     <string name="debug_layout" msgid="5981361776594526155">"Прикажи граници на слој"</string>
     <string name="debug_layout_summary" msgid="2001775315258637682">"Прикажи граници на клип, маргини, итн."</string>
     <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Сила на RTL за насока на слој"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 7194505..41a116e 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -324,7 +324,7 @@
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏതാണ്ട് <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന് <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഫുൾ ചാർജാകാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 85d6002..97a9c53 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -137,7 +137,7 @@
     <item msgid="364670732877872677">"အကောင်းဆုံးကြိုးပမ်းမှု (ပေးပို့နှုန်း အလိုက်)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
-    <item msgid="8665206199209698501">"ပိတ်ပါ"</item>
+    <item msgid="8665206199209698501">"ပိတ်ရန်"</item>
     <item msgid="1593289376502312923">"64K"</item>
     <item msgid="487545340236145324">"256K"</item>
     <item msgid="2423528675294333831">"1M"</item>
@@ -145,13 +145,13 @@
     <item msgid="2803199102589126938">"16M"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
-    <item msgid="6089470720451068364">"ပိတ်ပါ"</item>
+    <item msgid="6089470720451068364">"ပိတ်ရန်"</item>
     <item msgid="4622460333038586791">"64K"</item>
     <item msgid="2212125625169582330">"256K"</item>
     <item msgid="1704946766699242653">"1M"</item>
   </string-array>
   <string-array name="select_logd_size_summaries">
-    <item msgid="6921048829791179331">"ပိတ်ပါ"</item>
+    <item msgid="6921048829791179331">"ပိတ်ရန်"</item>
     <item msgid="2969458029344750262">"မှတ်တမ်းယာယီကြားခံနယ်တစ်ခုလျှင် 64K"</item>
     <item msgid="1342285115665698168">"မှတ်တမ်းယာယီကြားခံနယ်တစ်ခုလျှင် 256K"</item>
     <item msgid="1314234299552254621">"မှတ်တမ်းယာယီကြားခံနယ်တစ်ခုလျှင် 1M"</item>
@@ -159,13 +159,13 @@
     <item msgid="5431354956856655120">"မှတ်တမ်းယာယီကြားခံနယ်တစ်ခုလျှင် 16M"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
-    <item msgid="1744840221860799971">"ပိတ်ပါ"</item>
+    <item msgid="1744840221860799971">"ပိတ်ရန်"</item>
     <item msgid="3054662377365844197">"အားလုံး"</item>
     <item msgid="688870735111627832">"ရေဒီယိုမှလွဲ၍ အားလုံး"</item>
     <item msgid="2850427388488887328">"ကာနယ်သာ"</item>
   </string-array>
   <string-array name="select_logpersist_summaries">
-    <item msgid="2216470072500521830">"ပိတ်ပါ"</item>
+    <item msgid="2216470072500521830">"ပိတ်ရန်"</item>
     <item msgid="172978079776521897">"မှတ်တမ်းသိမ်းဆည်းရန် လျာထားချက်များ အားလုံး"</item>
     <item msgid="3873873912383879240">"ရေဒီယို မှတ်တမ်းသိမ်းဆည်းရန်လျာထားချက်မှလွဲ၍ အားလုံး"</item>
     <item msgid="8489661142527693381">"ကာနယ်မှတ်တမ်းသိမ်းဆည်းရန် လျာထားချက်သာ"</item>
@@ -218,17 +218,17 @@
     <item msgid="1340692776955662664">"glGetError အမှားတက်လျှင်ခေါ်သောလုပ်ငန်းစဉ်"</item>
   </string-array>
   <string-array name="show_non_rect_clip_entries">
-    <item msgid="993742912147090253">"ပိတ်"</item>
+    <item msgid="993742912147090253">"ပိတ်ရန်"</item>
     <item msgid="675719912558941285">"စတုဂံမဟုတ်သော ဖောက်ရန်အပိုင်းကို အပြာရောင်ဖြင့်ဆွဲပါ"</item>
     <item msgid="1064373276095698656">"စမ်းသပ်ထားသော ပုံဆွဲရန်ညွှန်ကြားချက်များကို အစိမ်းရောင်ဖြင့် အသားပေး ဖော်ပြပါ"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
-    <item msgid="2193584639058893150">"ပိတ်"</item>
+    <item msgid="2193584639058893150">"ပိတ်ရန်"</item>
     <item msgid="2751513398307949636">"ဖန်သားပြင်ပေါ်မှာ မျဉ်းတန်းကဲ့သို့"</item>
     <item msgid="2355151170975410323">"<xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g> ဖြင့်"</item>
   </string-array>
   <string-array name="debug_hw_overdraw_entries">
-    <item msgid="8190572633763871652">"ပိတ်"</item>
+    <item msgid="8190572633763871652">"ပိတ်ရန်"</item>
     <item msgid="7688197031296835369">"ရှိရင်းစွဲထက်ပိုသော ဧရိယာများကိုပြရန်"</item>
     <item msgid="2290859360633824369">"အရောင်ရောနှောသောဧရိယာများပြရန်"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 21bc2dc..c2e8a94 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -82,7 +82,7 @@
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"ပင်နံပါတ် သို့မဟုတ် ဖြတ်သန်းခွင့်ကီးမမှန်ကန်သောကြောင့်<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့် တွဲချိတ်မရပါ။"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်ဆက်သွယ်မရပါ"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="1648157108520832454">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်တွဲချိတ်ရန် ပယ်ချခံရသည်"</string>
-    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi  မရှိ"</string>
+    <string name="accessibility_wifi_off" msgid="1166761729660614716">"Wi-Fi  ပိတ်ထားသည်"</string>
     <string name="accessibility_no_wifi" msgid="8834610636137374508">"Wi-Fi  ချိတ်ဆက်ထားမှု မရှိပါ"</string>
     <string name="accessibility_wifi_one_bar" msgid="4869376278894301820">"Wi-Fi  ၁ ဘားရှိ"</string>
     <string name="accessibility_wifi_two_bars" msgid="3569851234710034416">"Wi-Fi  ၂ ဘား"</string>
@@ -91,9 +91,9 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android စနစ်"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ဖယ်ရှားထားသော အက်ပ်များ"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ဖယ်ရှားထားသော အပလီကေးရှင်းနှင့် သုံးစွဲသူများ"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USBမှတဆင့်ချိတ်ဆက်ခြင်း"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB သုံး၍ချိတ်ဆက်ခြင်း"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ရွေ့လျားနိုင်သောဟော့စပေါ့"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ဘလူးတုသ်တဆင့်ပြန်ချိတ်ဆက်"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ဘလူးတုသ်သုံးချိတ်ဆက်ခြင်း"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"တဆင့်ပြန်လည်ချိတ်ဆက်ခြင်း"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"တဆင့်ချိတ်ဆက်ခြင်း၊ ဟော့စပေါ့"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"အလုပ်သုံးအက်ပ်များအားလုံး"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 8738e04..2f61e8c 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -103,7 +103,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"केही पूर्वनिर्धारितहरू सेट गरिएका छन्"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"कुनै पूर्वनिर्धारित सेट गरिएको छैन"</string>
     <string name="tts_settings" msgid="8186971894801348327">"पाठ-वाचन सेटिङहरू"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"पाठ-बाट-वाणी उत्पादन"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"पाठवाचकको उत्पादन"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"वाणी दर"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"पाठ वाचन हुने गति"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"पिच"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 30cd8db..77e311e 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -115,7 +115,7 @@
     <string name="tts_play_example_title" msgid="7094780383253097230">"Luisteren naar een voorbeeld"</string>
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Een korte demonstratie van spraaksynthese afspelen"</string>
     <string name="tts_install_data_title" msgid="4264378440508149986">"Spraakgegevens installeren"</string>
-    <string name="tts_install_data_summary" msgid="5742135732511822589">"De stemgegevens voor spraaksynthese installeren"</string>
+    <string name="tts_install_data_summary" msgid="5742135732511822589">"De spraakgegevens voor spraaksynthese installeren"</string>
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"Deze engine voor spraaksynthese kan mogelijk alle tekst verzamelen die wordt gesproken, waaronder persoonlijke gegevens zoals wachtwoorden en creditcardnummers. Deze engine is afkomstig van de <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>-engine. Het gebruik van deze engine voor spraaksynthese inschakelen?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Deze taal heeft een werkende netwerkverbinding nodig voor tekst-naar-spraak-uitvoer."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Dit is een voorbeeld van spraaksynthese"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 1e55e15..8534e856 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -91,9 +91,9 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"ਹਟਾਏ ਗਏ ਐਪਸ"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"ਹਟਾਏ ਗਏ ਐਪਸ ਅਤੇ ਉਪਭੋਗਤਾ"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ਟੀਥਰਿੰਗ"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB ਟੈਦਰਿੰਗ"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"ਪੋਰਟੇਬਲ ਹੌਟਸਪੌਟ"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth ਟੀਥਰਿੰਗ"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Bluetooth ਟੈਦਰਿੰਗ"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"ਟੀਥਰਿੰਗ"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"ਟੀਥਰਿੰਗ &amp; ਪੋਰਟੇਬਲ ਹੌਟਸਪੌਟ"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"ਸਾਰੀਆਂ ਕੰਮ ਐਪਾਂ"</string>
@@ -119,7 +119,7 @@
     <string name="tts_engine_security_warning" msgid="8786238102020223650">"ਇਹ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਉਹ ਸਾਰਾ ਟੈਕਸਟ ਇਕੱਤਰ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੋ ਸਕਦਾ ਹੈ, ਜੋ ਬੋਲਿਆ ਜਾਏਗਾ, ਨਿੱਜੀ ਡੈਟਾ ਸਮੇਤ ਜਿਵੇਂ ਪਾਸਵਰਡ ਅਤੇ ਕ੍ਰੈਡਿਟ ਕਾਰਡ ਨੰਬਰ। ਇਹ <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> ਇੰਜਣ ਤੋਂ ਆਉਂਦਾ ਹੈ। ਕੀ ਇਸ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਇੰਜਣ ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਹੈ?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"ਇਸ ਭਾਸ਼ਾ ਲਈ ਟੈਕਸਟ-ਟੂ-ਸਪੀਚ ਆਊਟਪੁਟ ਲਈ ਇੱਕ ਚਾਲੂ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੀ ਲੋੜ ਹੈ।"</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"ਇਹ ਸਪੀਚ ਸਿੰਥੈਸਿਸ ਦਾ ਇੱਕ ਉਦਾਹਰਨ ਹੈ"</string>
-    <string name="tts_status_title" msgid="7268566550242584413">"ਡਿਫੌਲਟ ਭਾਸ਼ਾ ਸਥਿਤੀ"</string>
+    <string name="tts_status_title" msgid="7268566550242584413">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਭਾਸ਼ਾ ਸਥਿਤੀ"</string>
     <string name="tts_status_ok" msgid="1309762510278029765">"<xliff:g id="LOCALE">%1$s</xliff:g> ਪੂਰੀ ਤਰ੍ਹਾਂ ਸਮਰਥਿਤ ਹੈ"</string>
     <string name="tts_status_requires_network" msgid="6042500821503226892">"<xliff:g id="LOCALE">%1$s</xliff:g> ਲਈ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਲੁੜੀਂਦਾ ਹੈ"</string>
     <string name="tts_status_not_supported" msgid="4491154212762472495">"<xliff:g id="LOCALE">%1$s</xliff:g> ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
@@ -285,7 +285,7 @@
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ਨਵਾਂ ਪਾਸਵਰਡ ਅਤੇ ਪੁਸ਼ਟੀ ਮੇਲ ਨਹੀਂ ਖਾਂਦੀ"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ਬੈਕਅਪ ਪਾਸਵਰਡ ਸੈਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲਤਾ"</string>
   <string-array name="color_mode_names">
-    <item msgid="2425514299220523812">"ਚਮਕੀਲਾ (ਡਿਫੌਲਟ)"</item>
+    <item msgid="2425514299220523812">"ਚਮਕੀਲਾ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
     <item msgid="8446070607501413455">"ਕੁਦਰਤੀ"</item>
     <item msgid="6553408765810699025">"ਸਟੈਂਡਰਡ"</item>
   </string-array>
@@ -306,8 +306,8 @@
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"ਤਬਦੀਲ ਕਰੋ ..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"ਫ਼ਾਈਲ ਪਹਿਲਾਂ ਤੋਂ ਇਨਕ੍ਰਿਪਟਡ ਹੈ"</string>
     <string name="title_convert_fbe" msgid="1263622876196444453">"ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਤਬਦੀਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
-    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ਡੈਟਾ ਪਾਰਟੀਸ਼ਨ ਨੂੰ ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਤਬਦੀਲ ਕਰੋ\n !!ਚੇਤਾਵਨੀ!! ਇਹ ਤੁਹਾਡੇ ਸਾਰੇ ਡੈਟੇ ਨੂੰ ਸਾਫ਼ ਕਰ ਦੇਵੇਗਾ\n ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਅਲਫਾ ਹੈ, ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।\n ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਮਿਟਾਓ ਅਤੇ ਤਬਦੀਲ ਕਰੋ...\' ਨੂੰ ਦਬਾਓ।"</string>
-    <string name="button_convert_fbe" msgid="5152671181309826405">"ਮਿਟਾਓ ਅਤੇ ਤਬਦੀਲ ਕਰੋ..."</string>
+    <string name="convert_to_fbe_warning" msgid="6139067817148865527">"ਡੈਟਾ ਪਾਰਟੀਸ਼ਨ ਦਾ ਫ਼ਾਈਲ ਆਧਾਰਿਤ ਇਨਕ੍ਰਿਪਸ਼ਨ ਵਿੱਚ ਰੁਪਾਂਤਰਣ ਕਰੋ\n !!ਚੇਤਾਵਨੀ!! ਇਹ ਤੁਹਾਡੇ ਸਾਰੇ ਡੈਟੇ ਨੂੰ ਮਿਟਾ ਦੇਵੇਗਾ\n ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਿਕ ਹੈ, ਅਤੇ ਸ਼ਾਇਦ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।\n ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਮਿਟਾਓ ਅਤੇ ਰੁਪਾਂਤਰਣ ਕਰੋ...\' ਨੂੰ ਦਬਾਓ।"</string>
+    <string name="button_convert_fbe" msgid="5152671181309826405">"ਮਿਟਾਓ ਅਤੇ ਰੁਪਾਂਤਰਣ ਕਰੋ..."</string>
     <string name="picture_color_mode" msgid="4560755008730283695">"ਤਸਵੀਰ ਰੰਗ ਮੋਡ"</string>
     <string name="picture_color_mode_desc" msgid="1141891467675548590">"sRGB ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"ਅਯੋਗ ਬਣਾਇਆ"</string>
@@ -345,9 +345,9 @@
     <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ਬਾਕੀ"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"ਛੋਟਾ"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
-    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ਵੱਡਾ"</string>
-    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ਥੋੜ੍ਹਾ ਵੱਡਾ"</string>
-    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ਸਭ ਤੋਂ ਵੱਡਾ"</string>
+    <string name="screen_zoom_summary_large" msgid="4835294730065424084">"ਵੱਡੀ"</string>
+    <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"ਥੋੜ੍ਹਾ ਵੱਡੀ"</string>
+    <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"ਸਭ ਤੋਂ ਵੱਡੀ"</string>
     <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
     <string name="help_feedback_label" msgid="6815040660801785649">"ਮਦਦ ਅਤੇ ਪ੍ਰਤੀਕਰਮ"</string>
     <string name="content_description_menu_button" msgid="8182594799812351266">"ਮੀਨੂ"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index fead9f0..80b8990 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automaticamente via provedor de avaliação de rede"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index fead9f0..80b8990 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"Fora do alcance"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Não se conectará automaticamente"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"Sem acesso à Internet"</string>
-    <string name="saved_network" msgid="4352716707126620811">"Salvas por <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="saved_network" msgid="4352716707126620811">"Salva por <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"Conectado automaticamente via %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Conectado automaticamente via provedor de avaliação de rede"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado via %1$s"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 9504a73..0ae7049 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -324,7 +324,7 @@
     <string name="power_discharging_duration" msgid="2843747179907396142">"<xliff:g id="LEVEL">%1$s</xliff:g> - încă aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcarea completă"</string>
     <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 75b766b..028d561 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -344,7 +344,7 @@
     <string name="charge_length_format" msgid="8978516217024434156">"pred <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"Zostáva <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
-    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predvolená"</string>
+    <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Predvolené"</string>
     <string name="screen_zoom_summary_large" msgid="4835294730065424084">"Veľké"</string>
     <string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Väčšie"</string>
     <string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Najväčšie"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 8b24ef7..a6ad468 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -106,7 +106,7 @@
     <string name="tts_settings_title" msgid="1237820681016639683">"Kubadilisha maandishi hadi usemi"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Kasi ya kutamka"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Kasi ya kutamkwa kwa maneno"</string>
-    <string name="tts_default_pitch_title" msgid="6135942113172488671">"Giza"</string>
+    <string name="tts_default_pitch_title" msgid="6135942113172488671">"Uzito wa sauti"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Huathiri sauti ya matamshi yaliyounganishwa"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Lugha"</string>
     <string name="tts_lang_use_system" msgid="2679252467416513208">"Tumia lugha ya mfumo"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 34dd863..910e66c 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -91,9 +91,9 @@
     <string name="process_kernel_label" msgid="3916858646836739323">"Hệ điều hành Android"</string>
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Ứng dụng đã xóa"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Ứng dụng và người dùng bị xóa"</string>
-    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Truy cập Internet qua USB"</string>
+    <string name="tether_settings_title_usb" msgid="6688416425801386511">"Chia sẻ kết nối Internet qua USB"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Điểm phát sóng di động"</string>
-    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Truy cập Internet qua Bluetooth"</string>
+    <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Chia sẻ kết nối Internet qua Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Đang dùng làm điểm truy cập Internet"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"USB Internet &amp; điểm truy cập di động"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Tất cả ứng dụng làm việc"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index ac7cd4e..b224c23 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -313,7 +313,7 @@
     <string name="daltonizer_mode_disabled" msgid="7482661936053801862">"已停用"</string>
     <string name="daltonizer_mode_monochromacy" msgid="8485709880666106721">"全色盲"</string>
     <string name="daltonizer_mode_deuteranomaly" msgid="5475532989673586329">"绿色弱视(红绿不分)"</string>
-    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"红色弱视(红绿色)"</string>
+    <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"红色弱视(红绿不分)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"蓝色弱视(蓝黄色)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"这是实验性功能,性能可能不稳定。"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 484f1d3..03081af 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -31,7 +31,7 @@
     <string name="wifi_not_in_range" msgid="1136191511238508967">"超出可用範圍"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"不會自動連線"</string>
     <string name="wifi_no_internet" msgid="3880396223819116454">"無法偵測互聯網連線"</string>
-    <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> 的儲存"</string>
+    <string name="saved_network" msgid="4352716707126620811">"由「<xliff:g id="NAME">%1$s</xliff:g>」儲存"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"已透過 %1$s 自動連線"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已透過網絡評分供應商自動連線"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"已透過 %1$s 連線"</string>
@@ -316,7 +316,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"紅色弱視 (紅綠)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"藍色弱視 (藍黃)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是實驗性功能,效能尚待改善。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
     <string name="power_remaining_duration_only" msgid="845431008899029842">"剩餘約 <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g>後就能充滿電"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/SecureTouchListener.java b/packages/SettingsLib/src/com/android/settingslib/SecureTouchListener.java
new file mode 100644
index 0000000..766c42b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/SecureTouchListener.java
@@ -0,0 +1,44 @@
+package com.android.settingslib;
+
+import android.os.SystemClock;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Toast;
+
+/**
+ * A touch listener which consumes touches when another window is partly or wholly obscuring the
+ * window containing the view this listener is attached to.
+ * Optionally accepts a string to show the user as a toast when consuming an insecure touch
+ */
+public class SecureTouchListener implements View.OnTouchListener {
+
+    private static final long TAP_DEBOUNCE_TIME = 2000;
+    private long mLastToastTime = 0;
+    private String mWarningText;
+
+    public SecureTouchListener() {
+        this(null);
+    }
+
+    public SecureTouchListener(String warningText) {
+        mWarningText = warningText;
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0
+                || (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0) {
+            if (mWarningText != null) {
+                // Show a toast warning the user
+                final long currentTime = SystemClock.uptimeMillis();
+                if (currentTime - mLastToastTime > TAP_DEBOUNCE_TIME) {
+                    mLastToastTime = currentTime;
+                    Toast.makeText(v.getContext(), mWarningText, Toast.LENGTH_SHORT).show();
+                }
+            }
+            // Consume the touch event
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index b54d7e20..b760ad4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -32,20 +32,25 @@
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
+import android.text.format.DateUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Xml;
 import android.view.InflateException;
+
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.drawer.TileUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 public class SuggestionParser {
 
@@ -104,8 +109,8 @@
     private final String mSmartDismissControl;
 
 
-    public SuggestionParser(
-        Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
+    public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml,
+            String smartDismissControl) {
         this(
                 context,
                 sharedPrefs,
@@ -114,7 +119,7 @@
     }
 
     public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
-       this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
+        this(context, sharedPrefs, orderXml, DEFAULT_SMART_DISMISS_CONTROL);
     }
 
     @VisibleForTesting
@@ -138,19 +143,25 @@
         final int N = mSuggestionList.size();
         for (int i = 0; i < N; i++) {
             final SuggestionCategory category = mSuggestionList.get(i);
-            if (category.exclusive) {
+            if (category.exclusive && !isExclusiveCategoryExpired(category)) {
                 // If suggestions from an exclusive category are present, parsing is stopped
                 // and only suggestions from that category are displayed. Note that subsequent
                 // exclusive categories are also ignored.
-                List<Tile> exclusiveSuggestions = new ArrayList<>();
-                readSuggestions(category, exclusiveSuggestions, isSmartSuggestionEnabled);
+                final List<Tile> exclusiveSuggestions = new ArrayList<>();
+
+                // Read suggestion and force isSmartSuggestion to be false so the rule defined
+                // from each suggestion itself is used.
+                readSuggestions(category, exclusiveSuggestions, false /* isSmartSuggestion */);
                 if (!exclusiveSuggestions.isEmpty()) {
                     return exclusiveSuggestions;
                 }
             } else {
+                // Either the category is not exclusive, or the exclusiveness expired so we should
+                // treat it as a normal category.
                 readSuggestions(category, suggestions, isSmartSuggestionEnabled);
             }
         }
+        dedupeSuggestions(suggestions);
         return suggestions;
     }
 
@@ -177,7 +188,7 @@
 
     @VisibleForTesting
     public void filterSuggestions(
-        List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
+            List<Tile> suggestions, int countBefore, boolean isSmartSuggestionEnabled) {
         for (int i = countBefore; i < suggestions.size(); i++) {
             if (!isAvailable(suggestions.get(i)) ||
                     !isSupported(suggestions.get(i)) ||
@@ -190,9 +201,25 @@
         }
     }
 
+    /**
+     * Filter suggestions list so they are all unique.
+     */
+    private void dedupeSuggestions(List<Tile> suggestions) {
+        final Set<String> intents = new ArraySet<>();
+        for (int i = suggestions.size() - 1; i >= 0; i--) {
+            final Tile suggestion = suggestions.get(i);
+            final String intentUri = suggestion.intent.toUri(Intent.URI_INTENT_SCHEME);
+            if (intents.contains(intentUri)) {
+                suggestions.remove(i);
+            } else {
+                intents.add(intentUri);
+            }
+        }
+    }
+
     @VisibleForTesting
     void readSuggestions(
-        SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
+            SuggestionCategory category, List<Tile> suggestions, boolean isSmartSuggestionEnabled) {
         int countBefore = suggestions.size();
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(category.category);
@@ -304,7 +331,7 @@
         final boolean isConnectionRequired =
                 suggestion.metaData.getBoolean(META_DATA_IS_CONNECTION_REQUIRED);
         if (!isConnectionRequired) {
-          return true;
+            return true;
         }
         ConnectivityManager cm =
                 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -326,6 +353,25 @@
         Settings.Secure.putInt(mContext.getContentResolver(), name, 1);
     }
 
+    /**
+     * Whether or not the category's exclusiveness has expired.
+     */
+    private boolean isExclusiveCategoryExpired(SuggestionCategory category) {
+        final String keySetupTime = category.category + SETUP_TIME;
+        final long currentTime = System.currentTimeMillis();
+        if (!mSharedPrefs.contains(keySetupTime)) {
+            mSharedPrefs.edit()
+                    .putLong(keySetupTime, currentTime)
+                    .commit();
+        }
+        if (category.exclusiveExpireDaysInMillis < 0) {
+            // negative means never expires
+            return false;
+        }
+        final long setupTime = mSharedPrefs.getLong(keySetupTime, 0);
+        return currentTime - setupTime > category.exclusiveExpireDaysInMillis;
+    }
+
     private boolean isDismissed(Tile suggestion, boolean isSmartSuggestionEnabled) {
         String dismissControl = getDismissControl(suggestion, isSmartSuggestionEnabled);
         if (dismissControl == null) {
@@ -384,6 +430,7 @@
         public String pkg;
         public boolean multiple;
         public boolean exclusive;
+        public long exclusiveExpireDaysInMillis;
     }
 
     private static class SuggestionOrderInflater {
@@ -394,6 +441,7 @@
         private static final String ATTR_PACKAGE = "package";
         private static final String ATTR_MULTIPLE = "multiple";
         private static final String ATTR_EXCLUSIVE = "exclusive";
+        private static final String ATTR_EXCLUSIVE_EXPIRE_DAYS = "exclusiveExpireDays";
 
         private final Context mContext;
 
@@ -471,6 +519,12 @@
                 String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
                 category.exclusive =
                         !TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
+                String expireDaysAttr = attrs.getAttributeValue(null,
+                        ATTR_EXCLUSIVE_EXPIRE_DAYS);
+                long expireDays = !TextUtils.isEmpty(expireDaysAttr)
+                        ? Integer.parseInt(expireDaysAttr)
+                        : -1;
+                category.exclusiveExpireDaysInMillis = DateUtils.DAY_IN_MILLIS * expireDays;
                 return category;
             } else {
                 throw new IllegalArgumentException("Unknown item " + name);
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 151e0ea..abbef70 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -17,13 +17,19 @@
 
 import android.content.Context;
 import android.os.SystemProperties;
+import android.support.annotation.VisibleForTesting;
 import android.telephony.CarrierConfigManager;
 
 public class TetherUtil {
 
-    private static boolean isEntitlementCheckRequired(Context context) {
+    @VisibleForTesting
+    static boolean isEntitlementCheckRequired(Context context) {
         final CarrierConfigManager configManager = (CarrierConfigManager) context
              .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager == null || configManager.getConfig() == null) {
+            // return service default
+            return true;
+        }
         return configManager.getConfig().getBoolean(CarrierConfigManager
              .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index ea28fe6..5a57e69 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -152,6 +152,12 @@
         final MeasurementDetails details = new MeasurementDetails();
         if (mVolume == null) return details;
 
+        if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) {
+            details.totalSize = mVolume.getPath().getTotalSpace();
+            details.availSize = mVolume.getPath().getUsableSpace();
+            return details;
+        }
+
         try {
             details.totalSize = mStats.getTotalBytes(mVolume.fsUuid);
             details.availSize = mStats.getFreeBytes(mVolume.fsUuid);
@@ -161,7 +167,6 @@
             return details;
         }
 
-
         final long finishTotal = SystemClock.elapsedRealtime();
         Log.d(TAG, "Measured total storage in " + (finishTotal - start) + "ms");
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
index d534180..9c21738 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SuggestionParserTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settingslib;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -36,19 +34,24 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.res.ResourceLoader;
 import org.robolectric.res.builder.DefaultPackageManager;
+import org.robolectric.res.builder.RobolectricPackageManager;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import static com.google.common.truth.Truth.assertThat;
+
 @RunWith(SettingLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SuggestionParserTest {
 
     private Context mContext;
+    private RobolectricPackageManager mPackageManager;
     private SuggestionParser mSuggestionParser;
     private SuggestionParser.SuggestionCategory mMultipleCategory;
     private SuggestionParser.SuggestionCategory mExclusiveCategory;
+    private SuggestionParser.SuggestionCategory mExpiredExclusiveCategory;
     private List<Tile> mSuggestionsBeforeDismiss;
     private List<Tile> mSuggestionsAfterDismiss;
     private SharedPreferences mPrefs;
@@ -59,6 +62,7 @@
         RuntimeEnvironment.setRobolectricPackageManager(
                 new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
         mContext = RuntimeEnvironment.application;
+        mPackageManager = RuntimeEnvironment.getRobolectricPackageManager();
         mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
         mSuggestion = new Tile();
         mSuggestion.intent = new Intent("action");
@@ -70,21 +74,36 @@
         mExclusiveCategory = new SuggestionParser.SuggestionCategory();
         mExclusiveCategory.category = "category2";
         mExclusiveCategory.exclusive = true;
-        mSuggestionParser = new SuggestionParser(
-                mContext, mPrefs, Arrays.asList(mMultipleCategory, mExclusiveCategory), "0,0");
+        mExpiredExclusiveCategory = new SuggestionParser.SuggestionCategory();
+        mExpiredExclusiveCategory.category = "category3";
+        mExpiredExclusiveCategory.exclusive = true;
+        mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
+
+        mSuggestionParser = new SuggestionParser(mContext, mPrefs,
+                Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
+                "0,0");
 
         ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
         info1.activityInfo.packageName = "pkg";
+        ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, "category1");
+        infoDupe1.activityInfo.packageName = "pkg";
+
         ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
         info2.activityInfo.packageName = "pkg2";
         ResolveInfo info3 = TileUtilsTest.newInfo(true, "category2");
         info3.activityInfo.packageName = "pkg3";
+        ResolveInfo info4 = TileUtilsTest.newInfo(true, "category3");
+        info4.activityInfo.packageName = "pkg4";
 
         Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
         Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
-        RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info1);
-        RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info2);
-        RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent2, info3);
+        Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3");
+
+        mPackageManager.addResolveInfoForIntent(intent1, info1);
+        mPackageManager.addResolveInfoForIntent(intent1, info2);
+        mPackageManager.addResolveInfoForIntent(intent1, infoDupe1);
+        mPackageManager.addResolveInfoForIntent(intent2, info3);
+        mPackageManager.addResolveInfoForIntent(intent3, info4);
     }
 
     @Test
@@ -115,16 +134,42 @@
     }
 
     @Test
-    public void testGetSuggestion_exclusiveNotAvailable() {
-        RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
+    public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() {
+        mPackageManager.removeResolveInfosForIntent(
                 new Intent(Intent.ACTION_MAIN).addCategory("category2"),
                 "pkg3");
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category3"),
+                "pkg4");
 
         // If exclusive item is not available, the other categories should be shown
         final List<Tile> suggestions = mSuggestionParser.getSuggestions();
+
         assertThat(suggestions).hasSize(2);
         assertThat(suggestions.get(0).category).isEqualTo("category1");
+        assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg");
         assertThat(suggestions.get(1).category).isEqualTo("category1");
+        assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2");
+    }
+
+    @Test
+    public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() {
+        // First remove permanent exclusive
+        mPackageManager.removeResolveInfosForIntent(
+                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
+                "pkg3");
+        // Set the other exclusive to be expired.
+        mPrefs.edit()
+                .putLong(mExpiredExclusiveCategory.category + "_setup_time",
+                        System.currentTimeMillis() - 1000)
+                .commit();
+
+        // If exclusive is expired, they should be shown together with the other categories
+        final List<Tile> suggestions = mSuggestionParser.getSuggestions();
+        assertThat(suggestions).hasSize(3);
+        assertThat(suggestions.get(0).category).isEqualTo("category1");
+        assertThat(suggestions.get(1).category).isEqualTo("category1");
+        assertThat(suggestions.get(2).category).isEqualTo("category3");
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
new file mode 100644
index 0000000..3b1c3ac
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TetherUtilTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib;
+
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class TetherUtilTest {
+
+    @Mock
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void isEntitlementCheckRequired_noConfigManager_returnTrue() {
+        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)).thenReturn(null);
+
+        assertThat(TetherUtil.isEntitlementCheckRequired(mContext)).isTrue();
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 4b304b2..14e2a85 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1142,28 +1142,55 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+
+        final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
+                SETTINGS_TYPE_SSAID, owningUserId);
+
         if (instantSsaid != null) {
             // Use the stored value if it is still valid.
             if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
-                return ssaid;
+                return mascaradeSsaidSetting(ssaidSettings, ssaid);
             }
             // The value has changed, update the stored value.
-            final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
-                    SETTINGS_TYPE_SSAID, owningUserId);
             final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
                     true, callingPkg.packageName);
             if (!success) {
                 throw new IllegalStateException("Failed to update instant app android id");
             }
-            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId, name);
+            Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID,
+                    owningUserId, name);
+            return mascaradeSsaidSetting(ssaidSettings, setting);
         }
 
         // Lazy initialize ssaid if not yet present in ssaid table.
         if (ssaid == null || ssaid.isNull() || ssaid.getValue() == null) {
-            return mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId);
+            Setting setting = mSettingsRegistry.generateSsaidLocked(callingPkg, owningUserId);
+            return mascaradeSsaidSetting(ssaidSettings, setting);
         }
 
-        return ssaid;
+        return mascaradeSsaidSetting(ssaidSettings, ssaid);
+    }
+
+    private Setting mascaradeSsaidSetting(SettingsState settingsState, Setting ssaidSetting) {
+        // SSAID settings are located in a dedicated table for internal bookkeeping
+        // but for the world they reside in the secure table, so adjust the key here.
+        // We have a special name when looking it up but want the world to see it as
+        // "android_id".
+        if (ssaidSetting != null) {
+            return settingsState.new Setting(ssaidSetting) {
+                @Override
+                public int getKey() {
+                    final int userId = getUserIdFromKey(super.getKey());
+                    return makeKey(SETTINGS_TYPE_SECURE, userId);
+                }
+
+                @Override
+                public String getName() {
+                    return Settings.Secure.ANDROID_ID;
+                }
+            };
+        }
+        return null;
     }
 
     private boolean insertSecureSetting(String name, String value, String tag,
@@ -1173,7 +1200,6 @@
                     + ", " + tag  + ", " + makeDefault + ", "  + requestingUserId
                     + ", " + forceNotify + ")");
         }
-
         return mutateSecureSetting(name, value, tag, makeDefault, requestingUserId,
                 MUTATION_OPERATION_INSERT, forceNotify, 0);
     }
@@ -1879,6 +1905,7 @@
         Bundle result = new Bundle();
         result.putString(Settings.NameValueTable.VALUE,
                 !setting.isNull() ? setting.getValue() : null);
+
         mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
         return result;
     }
diff --git a/packages/Shell/res/values-bs/strings.xml b/packages/Shell/res/values-bs/strings.xml
index fab8063..6abcc33 100644
--- a/packages/Shell/res/values-bs/strings.xml
+++ b/packages/Shell/res/values-bs/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Odaberite da podijelite izvještaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o upotrebi aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema koji mogu sadržavati lične i privatne informacije koje smatrate osjetljivima (poput podataka o korištenju aplikacije ili podataka o lokaciji). Izvještaje o greškama dijelite samo sa aplikacijama i osobama kojima vjerujete."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj opet"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Nije moguće pročitati izvještaj o grešci"</string>
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index c7bae66..8fa217d 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -31,6 +31,7 @@
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     SystemUIPluginLib \
+    android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java
index a91aa61..1b3519b 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/ColorExtractor.java
@@ -20,17 +20,21 @@
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Color;
+import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 
 import com.google.android.colorextraction.types.ExtractionType;
 import com.google.android.colorextraction.types.Tonal;
 
+import java.util.ArrayList;
+
 /**
  * Class to process wallpaper colors and generate a tonal palette based on them.
  */
 public class ColorExtractor implements WallpaperManager.OnColorsChangedListener {
     private static final String TAG = "ColorExtractor";
     private static final int FALLBACK_COLOR = Color.BLACK;
+    private static final float DARK_TEXT_LUMINOSITY = 0.7f;
 
     private int mMainFallbackColor = FALLBACK_COLOR;
     private int mSecondaryFallbackColor = FALLBACK_COLOR;
@@ -38,13 +42,14 @@
     private final GradientColors mLockColors;
     private final Context mContext;
     private final ExtractionType mExtractionType;
-    private OnColorsChangedListener mListener;
+    private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners;
 
     public ColorExtractor(Context context) {
         mContext = context;
         mSystemColors = new GradientColors();
         mLockColors = new GradientColors();
         mExtractionType = new Tonal();
+        mOnColorsChangedListeners = new ArrayList<>();
 
         WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
 
@@ -69,22 +74,18 @@
         }
     }
 
-    public void setListener(OnColorsChangedListener listener) {
-        mListener = listener;
-    }
-
     @Override
     public void onColorsChanged(WallpaperColors colors, int which) {
         if ((which & WallpaperManager.FLAG_LOCK) != 0) {
             extractInto(colors, mLockColors);
-            if (mListener != null) {
-                mListener.onColorsChanged(mLockColors, WallpaperManager.FLAG_LOCK);
+            for (OnColorsChangedListener listener : mOnColorsChangedListeners) {
+                listener.onColorsChanged(mLockColors, WallpaperManager.FLAG_LOCK);
             }
         }
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
             extractInto(colors, mSystemColors);
-            if (mListener != null) {
-                mListener.onColorsChanged(mSystemColors, WallpaperManager.FLAG_SYSTEM);
+            for (OnColorsChangedListener listener : mOnColorsChangedListeners) {
+                listener.onColorsChanged(mSystemColors, WallpaperManager.FLAG_SYSTEM);
             }
         }
     }
@@ -94,12 +95,25 @@
         if (inWallpaperColors == null) {
             return;
         }
-        mExtractionType.extractInto(inWallpaperColors, outGradientColors);
+        boolean success = mExtractionType.extractInto(inWallpaperColors, outGradientColors);
+        if (success) {
+            // Updating dark text support. We're going to verify if the mean luminosity
+            // is greater then a threshold.
+            float hsl[] = new float[3];
+            float meanLuminosity = 0;
+            ColorUtils.colorToHSL(outGradientColors.getMainColor(), hsl);
+            meanLuminosity += hsl[2];
+            ColorUtils.colorToHSL(outGradientColors.getSecondaryColor(), hsl);
+            meanLuminosity += hsl[2];
+            meanLuminosity /= 2;
+            outGradientColors.setSupportsDarkText(meanLuminosity >= DARK_TEXT_LUMINOSITY);
+        }
     }
 
     private void applyFallback(GradientColors outGradientColors) {
         outGradientColors.setMainColor(mMainFallbackColor);
         outGradientColors.setSecondaryColor(mSecondaryFallbackColor);
+        outGradientColors.setSupportsDarkText(false);
     }
 
     public void destroy() {
@@ -109,6 +123,14 @@
         }
     }
 
+    public void addOnColorsChangedListener(OnColorsChangedListener listener) {
+        mOnColorsChangedListeners.add(listener);
+    }
+
+    public void removeOnColorsChangedListener(OnColorsChangedListener listener) {
+        mOnColorsChangedListeners.remove(listener);
+    }
+
     public static class GradientColors {
         private int mMainColor = FALLBACK_COLOR;
         private int mSecondaryColor = FALLBACK_COLOR;
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
index e046fb3..e75d95a 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/drawable/GradientDrawable.java
@@ -171,7 +171,7 @@
         // (avoiding banding) by merging the background solid color into
         // the gradient directly
         RadialGradient radialGradient = new RadialGradient(x, y, radius,
-                mMainColor, mSecondaryColor, Shader.TileMode.CLAMP);
+                mSecondaryColor, mMainColor, Shader.TileMode.CLAMP);
         mPaint.setShader(radialGradient);
     }
 
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java
index 937107c..36cabc9 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/ExtractionType.java
@@ -31,7 +31,8 @@
      *
      * @param inWallpaperColors where to read from
      * @param outGradientColors object that should receive the colors
+     * @return true if successful
      */
-    void extractInto(WallpaperColors inWallpaperColors,
+    boolean extractInto(WallpaperColors inWallpaperColors,
             ColorExtractor.GradientColors outGradientColors);
 }
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
index a7b2b99..85cfdbb 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
@@ -38,14 +38,32 @@
     private static final float FIT_WEIGHT_S = 1.0f;
     private static final float FIT_WEIGHT_L = 10.0f;
 
+    // When extracting the main color, only consider colors
+    // present in at least MIN_COLOR_OCCURRENCE of the image
     private static final float MIN_COLOR_OCCURRENCE = 0.1f;
-    private static final float MIN_LUMINOSITY = 0.5f;
+    // When extracting the main color, ignore colors darker
+    // than this.
+    private static final float PREFERRED_LUMINOSITY = 0.2f;
 
-    public void extractInto(WallpaperColors wallpaperColors,
+    // Secondary color will be darker than the main color when
+    // main color is brighter than this variable.
+    private static final float MAX_COLOR_LUMINOSITY = 0.8f;
+    // Luminosity difference between main and secondary colors
+    // should never be greater then this.
+    private static final float MAX_LUMINOSITY_DISTANCE = 0.35f;
+
+    /**
+     * Grab colors from WallpaperColors as set them into GradientColors
+     *
+     * @param wallpaperColors input
+     * @param gradientColors output
+     * @return true if successful
+     */
+    public boolean extractInto(WallpaperColors wallpaperColors,
             ColorExtractor.GradientColors gradientColors) {
 
         if (wallpaperColors.getColors().size() == 0) {
-            return;
+            return false;
         }
         // Tonal is not really a sort, it takes a color from the extracted
         // palette and finds a best fit amongst a collection of pre-defined
@@ -72,8 +90,10 @@
             int colorValue = weightedColor.first.toArgb();
             ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
                     Color.blue(colorValue), hsl);
-            if (hsl[2] > MIN_LUMINOSITY) {
+            // Stop at the most common color that's bright enough
+            if (hsl[2] > PREFERRED_LUMINOSITY) {
                 bestColor = weightedColor;
+                break;
             }
         }
 
@@ -87,35 +107,54 @@
                 hsl);
         hsl[0] /= 360.0f; // normalize
 
-        // TODO, we're finding a tonal palette for a hue, not all components
+        // Find the palette that contains the closest color
         TonalPalette palette = findTonalPalette(hsl[0]);
 
-        // Fall back to population sort if we couldn't find a tonal palette
         if (palette == null) {
             Log.w(TAG, "Could not find a tonal palette!");
-            return;
+            return false;
         }
 
         int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]);
         if (fitIndex == -1) {
             Log.w(TAG, "Could not find best fit!");
-            return;
+            return false;
         }
         float[] h = fit(palette.h, hsl[0], fitIndex,
                 Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
         float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
         float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
 
-
-        hsl[0] = fract(h[0]) * 360.0f;
-        hsl[1] = s[0];
-        hsl[2] = l[0];
+        hsl[0] = fract(h[fitIndex]) * 360.0f;
+        hsl[1] = s[fitIndex];
+        hsl[2] = l[fitIndex];
         gradientColors.setMainColor(ColorUtils.HSLToColor(hsl));
 
-        hsl[0] = fract(h[1]) * 360.0f;
-        hsl[1] = s[1];
-        hsl[2] = l[1];
+        int secondColorIndex = fitIndex;
+        if (hsl[2] > MAX_COLOR_LUMINOSITY) {
+            for (int i = secondColorIndex - 1; i >= 0; i--) {
+                float distance = Math.abs(hsl[2] - l[i]);
+                if (distance > MAX_LUMINOSITY_DISTANCE) {
+                    break;
+                }
+                secondColorIndex = i;
+            }
+        } else {
+            for (int i = secondColorIndex + 1; i < h.length; i++) {
+                float distance = Math.abs(hsl[2] - l[i]);
+                if (distance > MAX_LUMINOSITY_DISTANCE) {
+                    break;
+                }
+                secondColorIndex = i;
+            }
+        }
+
+        hsl[0] = fract(h[secondColorIndex]) * 360.0f;
+        hsl[1] = s[secondColorIndex];
+        hsl[2] = l[secondColorIndex];
         gradientColors.setSecondaryColor(ColorUtils.HSLToColor(hsl));
+
+        return true;
     }
 
     private static void populationSort(@NonNull WallpaperColors wallpaperColors) {
@@ -130,7 +169,7 @@
      * @param index which index to calculate the delta against
      * @param min minimum accepted value (clamp)
      * @param max maximum accepted value (clamp)
-     * @return
+     * @return new shifted palette
      */
     private static float[] fit(float[] data, float v, int index, float min, float max) {
         float[] fitData = new float[data.length];
@@ -143,21 +182,6 @@
         return fitData;
     }
 
-    /*function adjustSatLumForFit(val, points, fitIndex) {
-        var fitValue = lerpBetweenPoints(points, fitIndex);
-        var diff = val - fitValue;
-
-        var newPoints = [];
-        for (var ii=0; ii<points.length; ii++) {
-            var point = [points[ii][0], points[ii][1]];
-            point[1] += diff;
-            if (point[1] > 1) point[1] = 1;
-            if (point[1] < 0) point[1] = 0;
-            newPoints[ii] = point;
-        }
-        return newPoints;
-    }*/
-
     /**
      * Finds the closest color in a palette, given another HSL color
      *
@@ -257,43 +281,271 @@
 
     // Data definition of Material Design tonal palettes
     // When the sort type is set to TONAL, these palettes are used to find
-    // a best fist. Each palette is defined as 10 HSL colors
+    // a best fit. Each palette is defined as 22 HSL colors
     private static final TonalPalette[] TONAL_PALETTES = {
-            // Orange
             new TonalPalette(
-                    new float[] { 0.028f, 0.042f, 0.053f, 0.061f, 0.078f, 0.1f, 0.111f, 0.111f, 0.111f, 0.111f },
-                    new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f },
-                    new float[] { 0.5f, 0.53f, 0.54f, 0.55f, 0.535f, 0.52f, 0.5f, 0.63f, 0.75f, 0.85f }
+                    new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f,
+                            0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f,
+                            0.017543859649122865f},
+                    new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f,
+                            0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f,
+                            0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f,
+                            0.9254901960784314f}
             ),
-            // Yellow
             new TonalPalette(
-                    new float[] { 0.111f, 0.111f, 0.125f, 0.133f, 0.139f, 0.147f, 0.156f, 0.156f, 0.156f, 0.156f },
-                    new float[] { 1f, 0.942f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f },
-                    new float[] { 0.43f, 0.484f, 0.535f, 0.555f, 0.57f, 0.575f, 0.595f, 0.715f, 0.78f, 0.885f }
+                    new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f,
+                            0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f,
+                            0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f,
+                            0.5582010582010583f},
+                    new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
+                            0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f,
+                            1f, 1f, 1f},
+                    new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f,
+                            0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f,
+                            0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f,
+                            0.8764705882352941f}
             ),
-            // Green
             new TonalPalette(
-                    new float[] { 0.325f, 0.336f, 0.353f, 0.353f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f, 0.356f },
-                    new float[] { 1f, 1f, 0.852f, 0.754f, 0.639f, 0.667f, 0.379f, 0.542f, 1f, 1f },
-                    new float[] { 0.06f, 0.1f, 0.151f, 0.194f, 0.25f, 0.312f, 0.486f, 0.651f, 0.825f, 0.885f }
+                    new float[]{0.5669934640522876f, 0.5748031496062993f,
+                            0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f,
+                            0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f,
+                            0.508080808080808f, 0.5f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f},
+                    new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f,
+                            0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f,
+                            0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f}
             ),
-            // Blue
             new TonalPalette(
-                    new float[] { 0.631f, 0.603f, 0.592f, 0.586f, 0.572f, 0.544f, 0.519f, 0.519f, 0.519f, 0.519f },
-                    new float[] { 0.852f, 1f, 0.887f, 0.852f, 0.871f, 0.907f, 0.949f, 0.934f, 0.903f, 0.815f },
-                    new float[] { 0.34f, 0.38f, 0.482f, 0.497f, 0.536f, 0.571f, 0.608f, 0.696f, 0.794f, 0.892f }
+                    new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f,
+                            0.5f, 0.48724954462659376f, 0.4800347222222222f,
+                            0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f},
+                    new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f,
+                            0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
+                    new float[]{0.1588235294117647f, 0.21176470588235297f,
+                            0.25882352941176473f, 0.3f, 0.34901960784313724f,
+                            0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f,
+                            0.7509803921568627f, 0.8509803921568627f}
             ),
-            // Purple
             new TonalPalette(
-                    new float[] { 0.839f, 0.831f, 0.825f, 0.819f, 0.803f, 0.803f, 0.772f, 0.772f, 0.772f, 0.772f },
-                    new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 0.769f, 0.701f, 0.612f, 0.403f },
-                    new float[] { 0.125f, 0.15f, 0.2f, 0.245f, 0.31f, 0.36f, 0.567f, 0.666f, 0.743f, 0.833f }
+                    new float[]{0.3333333333333333f, 0.3333333333333333f,
+                            0.34006734006734f, 0.34006734006734f, 0.34006734006734f,
+                            0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f,
+                            0.3467741935483871f, 0.3703703703703704f},
+                    new float[]{0.6703296703296703f, 0.728813559322034f,
+                            0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
+                            0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
+                    new float[]{0.1784313725490196f, 0.23137254901960785f,
+                            0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
+                            0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
+                            0.8784313725490196f, 0.9294117647058824f}
             ),
-            // Red
             new TonalPalette(
-                    new float[] { 0.964f, 0.975f, 0.975f, 0.975f, 0.972f, 0.992f, 1.003f, 1.011f, 1.011f, 1.011f },
-                    new float[] { 0.869f, 0.802f, 0.739f, 0.903f, 1f, 1f, 1f, 1f, 1f, 1f },
-                    new float[] { 0.241f, 0.316f, 0.46f, 0.586f, 0.655f, 0.7f, 0.75f, 0.8f, 0.84f, 0.88f }
+                    new float[]{0.162280701754386f, 0.15032679738562088f,
+                            0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f,
+                            0.17824074074074076f, 0.18674698795180725f,
+                            0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f,
+                            0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f,
+                            0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f,
+                            0.8313725490196078f}
+            ),
+            new TonalPalette(
+                    new float[]{0.10619469026548674f, 0.11924686192468618f,
+                            0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f,
+                            0.16220238095238093f, 0.16666666666666666f,
+                            0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.44313725490196076f, 0.46862745098039216f,
+                            0.47843137254901963f, 0.5f, 0.5117647058823529f,
+                            0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f,
+                            0.8509803921568627f, 0.9f}
+            ),
+            new TonalPalette(
+                    new float[]{0.03561253561253561f, 0.05098039215686275f,
+                            0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f,
+                            0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f,
+                            0.15773809523809523f, 0.15359477124183002f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+                            0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9596491228070175f, 0.9593837535014005f,
+                            0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f,
+                            0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f,
+                            0.9754098360655739f, 0.9824561403508771f},
+                    new float[]{0.84070796460177f, 0.8206896551724138f,
+                            0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f,
+                            1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.22156862745098038f, 0.2843137254901961f,
+                            0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f,
+                            0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f,
+                            0.9254901960784314f}
+            ),
+            new TonalPalette(
+                    new float[]{0.841025641025641f, 0.8333333333333334f,
+                            0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
+                            0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
+                            0.7771084337349398f, 0.7747747747747749f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f,
+                            0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
+                    new float[]{0.12745098039215685f, 0.15490196078431373f,
+                            0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
+                            0.36470588235294116f, 0.44901960784313727f,
+                            0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f}
+            ),
+            new TonalPalette(
+                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+                    new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+                            0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+                            0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
+            ),
+            new TonalPalette(
+                    new float[]{0.955952380952381f, 0.9681069958847737f,
+                            0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
+                            0.009057971014492771f, 0.026748971193415648f,
+                            0.041666666666666616f, 0.05303030303030304f},
+                    new float[]{1f, 0.8350515463917526f, 0.6929460580912863f,
+                            0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f,
+                            0.8070175438596495f, 0.9310344827586209f, 1f, 1f},
+                    new float[]{0.27450980392156865f, 0.3803921568627451f,
+                            0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f,
+                            0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f,
+                            0.9058823529411765f, 0.9568627450980391f}
+            ),
+            new TonalPalette(
+                    new float[]{0.7514619883040936f, 0.7679738562091503f,
+                            0.7802083333333333f, 0.7844311377245509f, 0.796875f,
+                            0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f,
+                            0.8562091503267975f, 0.8666666666666667f},
+                    new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
+                            0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f,
+                            0.9560439560439562f, 1f, 1f},
+                    new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f,
+                            0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f,
+                            0.7333333333333334f, 0.8215686274509804f, 0.9f,
+                            0.9411764705882353f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f},
+                    new float[]{0.24590163934426232f, 0.17880794701986752f,
+                            0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f,
+                            0.16756756756756758f, 0.20312500000000017f,
+                            0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f},
+                    new float[]{0.2392156862745098f, 0.296078431372549f,
+                            0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f,
+                            0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f,
+                            0.8823529411764706f, 0.9372549019607843f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f,
+                            0.0047348484848484815f, 0.00316455696202532f, 0f,
+                            0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f},
+                    new float[]{1f, 0.7023255813953488f, 0.6638655462184874f,
+                            0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f,
+                            0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f,
+                            0.8181818181818189f},
+                    new float[]{0.27450980392156865f, 0.4215686274509804f,
+                            0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f,
+                            0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f,
+                            0.892156862745098f, 0.9568627450980391f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f,
+                            0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f,
+                            0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f,
+                            0.9444444444444444f},
+                    new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f,
+                            0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f,
+                            0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f},
+                    new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f,
+                            0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f,
+                            0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f,
+                            0.9411764705882353f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f,
+                            0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f,
+                            0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f,
+                            0.7333333333333333f},
+                    new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f,
+                            0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f,
+                            0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f,
+                            0.4545454545454551f},
+                    new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f,
+                            0.4176470588235294f, 0.45098039215686275f,
+                            0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f,
+                            0.8411764705882353f, 0.9352941176470588f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
+                            0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f,
+                            0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f,
+                            0.6428571428571429f},
+                    new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
+                            0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f,
+                            0.44360902255639095f,
+                            0.4499999999999997f, 0.4375000000000006f},
+                    new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
+                            0.40588235294117647f, 0.44705882352941173f,
+                            0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f,
+                            0.8431372549019608f, 0.9372549019607843f}
+            ),
+            new TonalPalette(
+                    new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f,
+                            0.48071625344352614f, 0.4829683698296837f, 0.484375f,
+                            0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f,
+                            0.4907407407407408f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
+                            0.41899441340782106f, 0.4128440366972478f,
+                            0.4090909090909088f},
+                    new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f,
+                            0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f,
+                            0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f}
+            ),
+            new TonalPalette(
+                    new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f,
+                            0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f,
+                            0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f,
+                            0.5666666666666667f},
+                    new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f,
+                            0.18343195266272191f, 0.18446601941747576f,
+                            0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f,
+                            0.15662650602409653f, 0.151515151515151f},
+                    new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f,
+                            0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f,
+                            0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f,
+                            0.9352941176470588f}
+            ),
+            new TonalPalette(
+                    new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
+                            0.03947368421052631f, 0.04166666666666668f,
+                            0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f,
+                            0.04444444444444459f, 0.05555555555555529f},
+                    new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
+                            0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f,
+                            0.15315315315315312f, 0.15189873417721522f,
+                            0.15789473684210534f, 0.15789473684210542f},
+                    new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
+                            0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f,
+                            0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f,
+                            0.9254901960784314f}
+            ),
+            new TonalPalette(
+                    new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f,
+                            0.10457516339869281f, 0.11699346405228758f,
+                            0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f,
+                            0.12500000000000003f, 0.12777777777777777f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f,
+                            0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f,
+                            0.9411764705882353f}
             )
     };
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 9ef05c5..7e7890d 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -112,6 +112,7 @@
         public boolean dualTarget = false;
         public boolean isTransient = false;
         public String expandedAccessibilityClassName;
+        public SlashState slash;
 
         public boolean copyTo(State other) {
             if (other == null) throw new IllegalArgumentException();
@@ -126,7 +127,8 @@
                     || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
                     || !Objects.equals(other.state, state)
                     || !Objects.equals(other.isTransient, isTransient)
-                    || !Objects.equals(other.dualTarget, dualTarget);
+                    || !Objects.equals(other.dualTarget, dualTarget)
+                    || !Objects.equals(other.slash, slash);
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
@@ -136,6 +138,7 @@
             other.state = state;
             other.dualTarget = dualTarget;
             other.isTransient = isTransient;
+            other.slash = slash != null ? slash.copy() : null;
             return changed;
         }
 
@@ -155,6 +158,7 @@
             sb.append(",dualTarget=").append(dualTarget);
             sb.append(",isTransient=").append(isTransient);
             sb.append(",state=").append(state);
+            sb.append(",slash=\"").append(slash).append("\"");
             return sb.append(']');
         }
 
@@ -246,4 +250,34 @@
         }
     }
 
+    @ProvidesInterface(version = SlashState.VERSION)
+    public static class SlashState {
+        public static final int VERSION = 2;
+
+        public boolean isSlashed;
+        public float rotation;
+
+        @Override
+        public String toString() {
+            return "isSlashed=" + isSlashed + ",rotation=" + rotation;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+            try {
+                return (((SlashState) o).rotation == rotation)
+                        && (((SlashState) o).isSlashed == isSlashed);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+
+        public SlashState copy() {
+            SlashState state = new SlashState();
+            state.rotation = rotation;
+            state.isSlashed = isSlashed;
+            return state;
+        }
+    }
 }
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 9bd05ae..0ec4ad5 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -30,7 +30,7 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="7504123374204446086">"Upišite PIN kôd za otključavanje"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Pogrešan PIN kôd."</string>
     <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
-    <string name="keyguard_plugged_in" msgid="89308975354638682">"Puni se"</string>
+    <string name="keyguard_plugged_in" msgid="89308975354638682">"Punjenje"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="8869226755413795173">"Brzo punjenje"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="6637043106038550407">"Sporo punjenje"</string>
     <string name="keyguard_low_battery" msgid="9218432555787624490">"Priključite punjač."</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index c570c89..6b06966 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -53,7 +53,7 @@
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Delete"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"‏השבתת ה-eSIM"</string>
     <string name="keyboardview_keycode_enter" msgid="4505833604411016668">"Enter"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"שכחתי את הקו"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="534245177645252620">"שכחתי את קו ביטול הנעילה"</string>
     <string name="kg_wrong_pattern" msgid="7620081431514773802">"קו ביטול הנעילה שגוי"</string>
     <string name="kg_wrong_password" msgid="4580683060277329277">"הסיסמה שגויה"</string>
     <string name="kg_wrong_pin" msgid="4785660766909463466">"קוד הגישה שגוי"</string>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
index 70e4780..30c10dc 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -14,16 +14,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"
-        android:fillAlpha=".3"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"
-        android:fillAlpha=".3"/>
+    android:width="32.0dp"
+    android:height="29.5dp"
+    android:viewportWidth="26.0"
+    android:viewportHeight="24.0">
+    <group
+        android:translateY="2">
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
index 09a67e1..c4ac7ffb 100644
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
@@ -45,7 +45,7 @@
             <group
                 android:name="plane"
                 android:translateX="23.481"
-                android:translateY="18.71151" >
+                android:translateY="15.71151" >
                 <path
                     android:name="plane_1"
                     android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
diff --git a/packages/SystemUI/res/drawable/rounded.xml b/packages/SystemUI/res/drawable/rounded.xml
new file mode 100644
index 0000000..ef7aea7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="8dp"
+    android:height="8dp"
+    android:viewportWidth="8"
+    android:viewportHeight="8">
+
+    <path
+        android:fillColor="#000000"
+        android:pathData="M8,0H0v8C0,3.6,3.6,0,8,0z" />
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/rounded_bg.xml b/packages/SystemUI/res/drawable/rounded_bg.xml
new file mode 100644
index 0000000..56aa9fe
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="#ffffffff" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
new file mode 100644
index 0000000..0201f28
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="#ffeeeeee" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="0dp"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full.xml b/packages/SystemUI/res/drawable/rounded_bg_full.xml
new file mode 100644
index 0000000..65d00de
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_full.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="#ffffffff" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="@dimen/corner_size"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="@dimen/corner_size"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
new file mode 100644
index 0000000..f6ee558
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="#ffeeeeee" />
+    <corners
+        android:bottomLeftRadius="@dimen/corner_size"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/corner_size"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
index 433da5f..2655bcd 100644
--- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
@@ -1,28 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.25dp"
-        android:height="18dp"
-        android:viewportWidth="46.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M20.4,18.0"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M42.0,32.0l0.0,-4.0L26.0,18.0L26.0,7.0c0.0,-1.7 -1.3,-3.0 -3.0,-3.0c-1.7,0.0 -3.0,1.3 -3.0,3.0l0.0,11.0L4.0,28.0l0.0,4.0l16.0,-5.0l0.0,11.0l-4.0,3.0l0.0,3.0l7.0,-2.0l7.0,2.0l0.0,-3.0l-4.0,-3.0L26.0,27.0L42.0,32.0z"/>
+    android:width="17.25dp"
+    android:height="18dp"
+    android:viewportWidth="19.65"
+    android:viewportHeight="20.5">
+    <group
+        android:translateX="1.3"
+        android:translateY="1.7">
+        <path
+            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
index 48c2222..0e9319c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
@@ -1,29 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2014 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
     android:insetRight="2.5dp">
-    <vector xmlns:android="http://schemas.android.com/apk/res/android"
+    <vector
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#ffffffff"
-            android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+        android:viewportWidth="19.3"
+        android:viewportHeight="19.3">
+        <group
+            android:translateX="1.2"
+            android:translateY="1.2">
+            <path
+                android:pathData="M0.97,3.97c-0.32,-0.33 -0.24,-0.81 0.08,-1.13L3.47,0.74C3.79,0.42 4.28,0.5 4.6,0.82s0.24,0.89 -0.08,1.13L2.1,4.05c-0.4,0.32 -0.89,0.24 -1.13,-0.08zM15.97,2.84l-2.5,-2.1c-0.32,-0.32 -0.8,-0.25 -1.13,0.08 -0.32,0.32 -0.24,0.81 0.08,1.13l2.5,2.1c0.33,0.3 0.81,0.24 1.13,-0.08 0.27,-0.31 0.25,-0.89 -0.08,-1.13zM15.73,9.21c0,4.03 -3.23,7.26 -7.26,7.26s-7.26,-3.23 -7.26,-7.26 3.23,-7.26 7.26,-7.26 7.26,3.23 7.26,7.26zM14.2,9.21c0,-3.15 -2.58,-5.73 -5.73,-5.73S2.74,6.06 2.74,9.21s2.58,5.73 5.73,5.73 5.73,-2.59 5.73,-5.73zM8.27,5.18c-0.33,0 -0.6,0.27 -0.6,0.6v4.23l3.34,2c0.27,0.17 0.62,0.08 0.79,-0.19s0.07,-0.64 -0.2,-0.8L8.87,9.41L8.87,5.78c0,-0.33 -0.27,-0.6 -0.6,-0.6z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
index e2d3539..4dc0e4b 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+        android:viewportWidth="17.0"
+        android:viewportHeight="17.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M8.84,8l2.62,-2.62c0.29,-0.29 0.29,-0.75 0,-1.04L8.33,1.22L8.31,1.2c-0.3,-0.28 -0.76,-0.26 -1.03,0.04c-0.13,0.13 -0.2,0.31 -0.2,0.5v4.51L4.24,3.4c-0.29,-0.29 -0.74,-0.29 -1.03,0s-0.29,0.74 0,1.03L6.78,8l-3.56,3.56c-0.29,0.29 -0.29,0.74 0,1.03s0.74,0.29 1.03,0l2.83,-2.83v4.51c0,0.4 0.33,0.73 0.73,0.73c0.18,0 0.36,-0.07 0.5,-0.2l0.03,-0.03l3.12,-3.12c0.29,-0.29 0.29,-0.75 0,-1.04L8.84,8zM8.47,6.37V3.36l1.5,1.5L8.47,6.37zM8.47,12.63V9.62l1.5,1.5L8.47,12.63z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
index 94c40ba..c8a4440 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17dp"
         android:height="17dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
index c36678d..366dbb5 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
@@ -1,34 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2016 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
-        <path
-            android:fillColor="#4DFFFFFF"
-            android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="19.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M11.5,8.5c0,0.41 -0.34,0.74 -0.74,0.74L9.24,9.24v1.5c0,0.41 -0.34,0.74 -0.74,0.74s-0.74,-0.34 -0.74,-0.74v-1.5h-1.5c-0.41,0 -0.74,-0.34 -0.74,-0.74s0.34,-0.74 0.74,-0.74h1.5v-1.5c0,-0.41 0.34,-0.74 0.74,-0.74s0.74,0.34 0.74,0.74v1.5h1.5c0.42,-0.01 0.76,0.33 0.76,0.74z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M13.23,12.05l0.99,0.57c0.19,0.12 0.25,0.38 0.12,0.55A7.452,7.452 0,0 1,7.5 15.9c-3.29,-0.44 -5.96,-3.08 -6.41,-6.38 -0.57,-4.17 2.33,-7.8 6.23,-8.42 0.23,-0.04 0.44,0.15 0.44,0.37v1.15c0,0.18 -0.14,0.33 -0.31,0.37 -2.7,0.52 -4.71,2.96 -4.55,5.83 0.16,2.86 2.57,5.21 5.43,5.29 1.77,0.06 3.38,-0.72 4.44,-1.97 0.11,-0.14 0.31,-0.18 0.46,-0.09z"
+                android:fillColor="#FFF" />
+            <path
+                android:pathData="M14.11,8.5c0,0.62 -0.11,1.22 -0.29,1.78 -0.06,0.17 0.01,0.35 0.16,0.45l1,0.57c0.19,0.12 0.46,0.03 0.54,-0.18 0.3,-0.82 0.47,-1.7 0.47,-2.62 0,-3.73 -2.73,-6.82 -6.31,-7.39a0.377,0.377 0,0 0,-0.44 0.37v1.15c0,0.18 0.14,0.33 0.31,0.36 2.59,0.51 4.56,2.78 4.56,5.51z"
+                android:fillAlpha="0.3"
+                android:fillColor="#FFF" />
+
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
index 3bf5e98..bd4cb0a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -1,28 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,1.59c-3.81,0 -6.91,3.09 -6.91,6.91s3.09,6.91 6.91,6.91 6.91,-3.09 6.91,-6.91 -3.1,-6.91 -6.91,-6.91zM11.16,9.56L5.84,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h5.31a1.06,1.06 0,0 1,0.01 2.12z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
index 82e25ca..41ed754 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
@@ -1,31 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-    Copyright (C) 2015 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
+    android:insetRight="2.5dp" >
     <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="16.6"
+        android:viewportHeight="16.6">
+        <group
+            android:translateX="-0.2"
+            android:translateY="-0.2">
+            <path
+                android:pathData="M8.5,3.72c-2.62,0 -4.78,2.16 -4.78,4.78s2.16,4.78 4.78,4.78 4.78,-2.16 4.78,-4.78 -2.07,-4.78 -4.78,-4.78zM10.09,9.56L6.91,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h3.19c0.59,0 1.06,0.48 1.06,1.06s-0.48,1.06 -1.07,1.06z"
+                android:fillColor="#FFF"/>
+            <path
+                android:pathData="M8.5,0.53C4.11,0.53 0.53,4.11 0.53,8.5s3.58,7.97 7.97,7.97 7.97,-3.58 7.97,-7.97S12.89,0.53 8.5,0.53zM8.5,15.28c-3.75,0 -6.78,-3.03 -6.78,-6.78S4.75,1.72 8.5,1.72s6.78,3.03 6.78,6.78 -3.03,6.78 -6.78,6.78z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
 </inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
index 2229c99..faea7d1 100644
--- a/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_no_sims.xml
@@ -1,25 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="?attr/backgroundColor"
-        android:pathData="M19.0,5.0c0.0,-1.1 -0.9,-2.0 -2.0,-2.0l-7.0,0.0L7.7,5.3L19.0,16.7L19.0,5.0zM3.7,3.9L2.4,5.2L5.0,7.8L5.0,19.0c0.0,1.1 0.9,2.0 2.0,2.0l10.0,0.0c0.4,0.0 0.7,-0.1 1.0,-0.3l1.9,1.9l1.3,-1.3L3.7,3.9z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="18.4"
+    android:viewportHeight="18.4">
+    <group
+        android:translateX="0.7"
+        android:translateY="1.0">
+        <path
+            android:pathData="M13.91,11.84L5.14,3.08l1.81,-1.81h5.41c0.85,0 1.54,0.69 1.54,1.54l0.01,9.03zM15.06,14.95L2.54,2.44c-0.28,-0.28 -0.71,-0.28 -0.99,0s-0.28,0.71 0,0.98l1.53,1.53v8.67c0,0.85 0.69,1.54 1.54,1.54h7.74c0.27,0 0.52,-0.07 0.74,-0.2l0.96,0.96c0.28,0.28 0.71,0.28 0.99,0 0.28,-0.26 0.28,-0.69 0.01,-0.97z"
+            android:fillColor="?attr/backgroundColor"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index eb7b4fc..e525fec 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -1,28 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="3dp"
-    android:insetRight="3dp">
-    <vector android:width="18dp"
-            android:height="18dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:width="19dp"
+        android:height="17dp"
+        android:viewportWidth="21.0"
+        android:viewportHeight="19.0">
+        <group
+            android:translateX="1.0"
+            android:translateY="1.0">
+            <path
+                android:pathData="M13.28,0.53L5.84,0.53c-0.88,0 -1.59,0.71 -1.59,1.59v12.75c0,0.88 0.71,1.59 1.59,1.59h7.44c0.88,0 1.59,-0.71 1.59,-1.59L14.87,2.12c0.01,-0.88 -0.71,-1.59 -1.59,-1.59zM13.28,14.88L5.84,14.88L5.84,2.12h7.44v12.76zM2.66,13.81a0.52,0.52 0,0 1,-0.53 -0.53L2.13,3.72c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v9.56c0,0.3 -0.24,0.53 -0.53,0.53zM0.53,11.69a0.52,0.52 0,0 1,-0.53 -0.53L0,5.84c0,-0.3 0.23,-0.53 0.53,-0.53 0.3,0 0.53,0.23 0.53,0.53v5.31c0,0.3 -0.23,0.54 -0.53,0.54zM16.47,13.81c0.3,0 0.53,-0.23 0.53,-0.53L17,3.72c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v9.56c0,0.3 0.23,0.53 0.53,0.53zM18.59,11.69c0.3,0 0.53,-0.23 0.53,-0.53L19.12,5.84c0,-0.3 -0.23,-0.53 -0.53,-0.53 -0.3,0 -0.53,0.23 -0.53,0.53v5.31c0,0.3 0.24,0.54 0.53,0.54z"
+                android:fillColor="#FFF"/>
+        </group>
     </vector>
-</inset>
\ No newline at end of file
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
index 7ca8c40..66f4fbb 100644
--- a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml
@@ -1,24 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.700000,10.000000c-0.800000,-2.300000 -3.000000,-4.000000 -5.700000,-4.000000c-3.300000,0.000000 -6.000000,2.700000 -6.000000,6.000000s2.700000,6.000000 6.000000,6.000000c2.600000,0.000000 4.800000,-1.700000 5.700000,-4.000000L17.000000,14.000000l0.000000,4.000000l4.000000,0.000000l0.000000,-4.000000l2.000000,0.000000l0.000000,-4.000000L12.700000,10.000000zM7.000000,14.000000c-1.100000,0.000000 -2.000000,-0.900000 -2.000000,-2.000000c0.000000,-1.100000 0.900000,-2.000000 2.000000,-2.000000s2.000000,0.900000 2.000000,2.000000C9.000000,13.100000 8.100000,14.000000 7.000000,14.000000z"/>
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="19.0"
+    android:viewportHeight="19.0">
+    <group
+        android:translateX="1.0"
+        android:translateY="1.0">
+        <path
+            android:pathData="M15.46,6.96H9a4.637,4.637 0,0 0,-4.37 -3.09C2.07,3.87 0,5.94 0,8.5s2.07,4.63 4.63,4.63c2.02,0 3.73,-1.29 4.37,-3.09h2.2v1.54a1.54,1.54 0,0 0,3.08 0v-1.54h1.16c0.87,0 1.56,-0.69 1.56,-1.54s-0.69,-1.54 -1.54,-1.54zM4.63,10.04a1.54,1.54 0,1 1,0.001 -3.081,1.54 1.54,0 0,1 -0.001,3.081z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
new file mode 100644
index 0000000..358833c
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- RelativeLayouts have an issue enforcing minimum heights, so just
+     work around this for now with LinearLayouts. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/global_actions_panel_width"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center_vertical"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="vertical"
+    android:paddingBottom="24dip"
+    android:paddingEnd="8dip"
+    android:paddingStart="8dip"
+    android:paddingTop="24dip">
+
+    <ImageView
+        android:id="@*android:id/icon"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_gravity="center"
+        android:scaleType="center"/>
+
+    <TextView
+        android:id="@*android:id/message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="center"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        />
+
+    <TextView
+        android:id="@*android:id/status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="center"
+        android:minHeight="26dp"
+        android:textColor="?android:attr/textColorTertiary"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
new file mode 100644
index 0000000..f409c03
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginBottom="0dp"
+    android:paddingTop="@dimen/global_actions_top_padding"
+    android:clipToPadding="false"
+    android:clipChildren="false">
+
+    <LinearLayout
+        android:id="@android:id/list"
+        android:layout_width="@dimen/global_actions_panel_width"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|end"
+        android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
+        android:orientation="vertical"
+        android:paddingTop="@dimen/volume_dialog_padding_top"
+        android:divider="@null"
+        android:dividerHeight="0dp"
+        android:translationZ="8dp">
+
+    </LinearLayout>
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 76315b8..eb74306 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -20,4 +20,4 @@
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
     android:layout_height="@dimen/notification_divider_height"
-    android:background="#FF616161" />
+    android:background="@color/notification_divider_color" />
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
new file mode 100644
index 0000000..8d391e0
--- /dev/null
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ImageView
+        android:id="@+id/left"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:tint="#ff000000"
+        android:src="@drawable/rounded" />
+    <ImageView
+        android:id="@+id/right"
+        android:layout_width="12dp"
+        android:layout_height="12dp"
+        android:tint="#ff000000"
+        android:layout_gravity="end"
+        android:src="@drawable/rounded" />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 18ffd0f..9076199 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -16,12 +16,12 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/volume_dialog"
-    android:layout_width="match_parent"
+    android:layout_width="@dimen/volume_dialog_panel_width"
     android:layout_height="wrap_content"
     android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
-    android:background="@drawable/volume_dialog_background"
+    android:layout_gravity="center_vertical|end"
     android:paddingTop="@dimen/volume_dialog_padding_top"
-    android:translationZ="4dp" >
+    android:translationZ="8dp" >
 
     <LinearLayout
         android:id="@+id/volume_dialog_content"
@@ -57,6 +57,7 @@
             android:layout_height="wrap_content"
             android:ellipsize="end"
             android:maxLines="1"
+            android:visibility="gone"
             android:textAppearance="@style/TextAppearance.Volume.Header" />
         <com.android.keyguard.AlphaOptimizedImageButton
             xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
new file mode 100644
index 0000000..57489fd
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/top_padding"
+    android:layout_marginBottom="@dimen/bottom_padding">
+
+    <include layout="@layout/volume_dialog"/>
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index aa1525d..7a93f8f 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -198,13 +198,13 @@
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Vliegtuigmodus aan."</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Vliegtuigmodus afgeskakel."</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Vliegtuigmodus aangeskakel."</string>
-    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"Moenie steur nie aan, net prioriteit."</string>
-    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Moenie steur nie; volkome stilte."</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\'Moenie steur nie\' is aan, net wekkers."</string>
-    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Moenie steur nie."</string>
-    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"Moenie steur nie af."</string>
-    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Moenie steur nie is afgeskakel."</string>
-    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Moenie steur nie is aangeskakel."</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"Moenie Steur Nie aan, net prioriteit."</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Moenie Steur Nie; volkome stilte."</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\'Moenie Steur Nie\' is aan, net wekkers."</string>
+    <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Moenie Steur Nie."</string>
+    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"Moenie Steur Nie af."</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Moenie Steur Nie is afgeskakel."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Moenie Steur Nie is aangeskakel."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth."</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth af."</string>
     <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth aan."</string>
@@ -266,7 +266,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Nageregkas"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Sluimerskerm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
-    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Moenie steur nie"</string>
+    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Moenie Steur Nie"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Net prioriteit"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Net wekkers"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Volkome stilte"</string>
@@ -622,7 +622,7 @@
     <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
     <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string>
     <string name="tuner_full_zen_title" msgid="4540823317772234308">"Wys saam met volumekontroles"</string>
-    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Moenie steur nie"</string>
+    <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Moenie Steur Nie"</string>
     <string name="volume_dnd_silent" msgid="4363882330723050727">"Volumeknoppieskortpad"</string>
     <string name="volume_up_silent" msgid="7141255269783588286">"Verlaat \'moenie steur nie\' met volume op"</string>
     <string name="battery" msgid="7498329822413202973">"Battery"</string>
@@ -755,10 +755,10 @@
     <string name="mobile_data" msgid="7094582042819250762">"Mobiele data"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is af"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"Bluetooth is af"</string>
-    <string name="dnd_is_off" msgid="6167780215212497572">"Moenie steur nie is af"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het \"Moenie steur nie\" aangeskakel."</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het \"Moenie steur nie\" aangeskakel."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"\'n Outomatiese reël of program het \"Moenie steur nie\" aangeskakel."</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"Moenie Steur Nie is af"</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"\'n Outomatiese reël (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"\'n Program (<xliff:g id="ID_1">%s</xliff:g>) het Moenie Steur Nie aangeskakel."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"\'n Outomatiese reël of program het Moenie Steur Nie aangeskakel."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"Tot <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Hou"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Vervang"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 76854f1..c083fd1 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -717,7 +717,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"يمكن ألا يعمل التطبيق مع وضع تقسيم الشاشة."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"التطبيق لا يتيح تقسيم الشاشة."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"التطبيق لا يسمح بتشغيله على شاشات عرض ثانوية."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"فتح الإعدادات."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"فتح الإعدادات السريعة."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"إغلاق الإعدادات السريعة."</string>
@@ -771,10 +771,10 @@
     <string name="mobile_data" msgid="7094582042819250762">"بيانات الجوّال"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"‏تم إيقاف شبكة Wi-Fi"</string>
     <string name="bt_is_off" msgid="2640685272289706392">"تم إيقاف البلوتوث."</string>
-    <string name="dnd_is_off" msgid="6167780215212497572">"تم إيقاف وضع \"الرجاء عدم الإزعاج\""</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"تم تشغيل وضع \"الرجاء عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
+    <string name="dnd_is_off" msgid="6167780215212497572">"تم إيقاف وضع \"عدم الإزعاج\""</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"تم تشغيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"تم تشغيل وضع \"عدم الإزعاج\" بواسطة تطبيق (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"تم تشغيل وضع \"عدم الإزعاج\" بواسطة قاعدة تلقائية أو تطبيق."</string>
     <string name="qs_dnd_until" msgid="3469471136280079874">"حتى <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"الإبقاء على الإعدادات"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"استبدال"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 4f508e8..7c2cc18 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -767,5 +767,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije pokrenute u pozadini"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste pregledali detalje o bateriji i potrošnji podataka"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i potrošnji podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 58bb004..8c4a617 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -232,7 +232,7 @@
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Інверсія колеру адключаецца."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Інверсія колеру ўключаецца."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мабільны хот-спот выключаецца."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільны хот-спот ўключаецца."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мабільная кропка доступу ўключаная."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Трансляцыя экрана спынена."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Рэжым працы выкл."</string>
     <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Рэжым працы ўкл."</string>
@@ -318,7 +318,7 @@
     <string name="quick_settings_connected" msgid="1722253542984847487">"Падлучана"</string>
     <string name="quick_settings_connecting" msgid="47623027419264404">"Падлучэнне..."</string>
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Мадэм"</string>
-    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Хот-спот"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Кропка доступу"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Апавяшчэнні"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ліхтарык"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мабільная перадача даных"</string>
@@ -527,7 +527,7 @@
     <string name="alarm_template" msgid="3980063409350522735">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"у <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Хуткія налады, <xliff:g id="TITLE">%s</xliff:g>."</string>
-    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Хот-спот"</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Кропка доступу"</string>
     <string name="accessibility_managed_profile" msgid="6613641363112584120">"Працоўны профіль"</string>
     <string name="tuner_warning_title" msgid="7094689930793031682">"Цікава для некаторых, але не для ўсіх"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"Наладка сістэмнага інтэрфейсу карыстальніка дае вам дадатковыя спосабы наладжвання і дапасоўвання карыстальніцкага інтэрфейсу Android. Гэтыя эксперыментальныя функцыі могуць змяніцца, перастаць працаваць або знікнуць у будучых версіях. Карыстайцеся з асцярожнасцю."</string>
@@ -710,8 +710,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Праграма можа не працаваць у рэжыме дзялення экрана."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Праграма не падтрымлівае функцыю дзялення экрана."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Праграма можа не працаваць на дадатковых дысплэях."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Праграма не падтрымлівае запуск на дадатковых дысплэях."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Праграма можа не працаваць на дадатковых экранах."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Праграма не падтрымлівае запуск на дадатковых экранах."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Адкрыць налады."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Адкрыць хуткія налады."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Закрыць хуткія налады."</string>
@@ -773,5 +773,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Пакінуць"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замяніць"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Праграмы, якія працуюць у фонавым рэжыме"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб атрымаць падрабязныя звесткі пра выкарыстанне трафіка і акумулятара"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб даведацца пра выкарыстанне трафіка і акумулятара"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index f649338..d818f28 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Запазване"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замяна"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работещи на заден план"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Докоснете за подробности относно използването на батерията и преноса на данни"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Докоснете за информация относно използването на батерията и преноса на данни"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index a0e0a25..4905db1 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -300,7 +300,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi uključen"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nema dostupnih Wi-Fi mreža"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prebacivanje"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Emitiranje"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za emitiranje"</string>
@@ -581,7 +581,7 @@
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="battery_panel_title" msgid="7944156115535366613">"Upotreba baterije"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
@@ -769,5 +769,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije koje rade u pozadini"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i prijenosu podataka"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 9457cf6..e5696f9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -700,7 +700,7 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'aplicació no admet la pantalla dividida."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Pot ser que l\'aplicació no funcioni en una pantalla secundària."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"L\'aplicació no es pot obrir en pantalles secundàries."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Obre la configuració."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Obre la configuració ràpida."</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Conserva"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substitueix"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacions que s\'estan executant en segon pla"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca per obtenir informació sobre l\'ús de dades i la bateria"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca per obtenir informació sobre l\'ús de dades i de bateria"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7a66789..5a859de 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g>-underretning: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i delt skærm."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke delt skærm."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Appen fungerer muligvis ikke på en sekundær skærm."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen kan ikke åbnes på en sekundær skærm."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Appen fungerer muligvis ikke på sekundære skærme."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen kan ikke åbnes på sekundære skærme."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Åbn Indstillinger."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Åbn Hurtige indstillinger."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Luk Hurtige indstillinger."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 5130e5b..d9af495 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Beibehalten"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ersetzen"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps, die im Hintergrund ausgeführt werden"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Für weitere Informationen zur Akku- und Datennutzung tippen"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Für Details zur Akku- und Datennutzung tippen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 44e9653..80f6065 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -700,7 +700,7 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Ειδοποίηση <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Δεν είναι δυνατή η λειτουργία της εφαρμογής με διαχωρισμό οθόνης."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Η εφαρμογή μπορεί να λειτουργεί σε μια δευτερεύουσα οθόνη."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Άνοιγμα ρυθμίσεων."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Άνοιγμα γρήγορων ρυθμίσεων."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 894fcb0..999d625 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -248,7 +248,7 @@
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Reanudar"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Con conexión Wi-Fi"</string>
-    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando señal GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
     <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
@@ -703,7 +703,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Es posible que la aplicación no funcione con la pantalla dividida."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"La aplicación no admite la pantalla dividida."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Es posible que la aplicación no funcione en una pantalla secundaria."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"La aplicación no se puede iniciar en pantallas secundarias."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"La aplicación no se puede abrir en pantallas secundarias."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Abrir ajustes."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Abrir ajustes rápidos."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Cerrar ajustes rápidos."</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Conservar"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicaciones que se están ejecutando en segundo plano"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para ver información detallada sobre el uso de datos y la batería"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para ver información detallada sobre el uso de datos y de la batería"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index c4a389ed..05085fa 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobiilne andmeside"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobiilne andmeside on sees"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobiilne andmeside on väljas"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetoothi jagamine."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Jagamine Bluetoothiga."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Lennurežiim."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN on sees."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"SIM-kaarti pole."</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 30ea6bf..6aadacb 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -702,8 +702,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> zerbitzuaren jakinarazpena: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikazioak ez du onartzen pantaila zatitua"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailan."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikazioak ez du onartzen bigarren mailako pantailarik."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Ireki ezarpenak."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Ireki ezarpen bizkorrak."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Itxi ezarpen bizkorrak."</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Utzi bere horretan"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateriaren eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 419e7f2..77a545e 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -703,7 +703,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"L\'application n\'est pas compatible avec l\'écran partagé."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"L\'application ne prend pas en charge le lancement sur les écrans secondaires."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Ouvrir les paramètres."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Ouvrir les réglages rapides."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Fermer les réglages rapides."</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Garder"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Applications qui fonctionnent en arrière-plan"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Touchez ici pour afficher des détails sur l\'usage de la pile et des données"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index acca9a6..3b3ef48 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -703,7 +703,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Application incompatible avec l\'écran partagé."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"L\'application ne peut être lancée sur des écrans secondaires."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"L\'application ne peut pas être lancée sur des écrans secondaires."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Ouvrir les paramètres."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Ouvrir la fenêtre de configuration rapide."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Fermer la fenêtre de configuration rapide."</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3bc73d1..05d41f0 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Substituír"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacións que se executan en segundo plano"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para obter información sobre a batería e o uso de datos"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para obter información sobre o uso de datos e a batería"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 43e6001..f2baa04 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> नोटिफ़िकेशन: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ऐप विभाजित स्‍क्रीन का समर्थन नहीं करता है."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"हो सकता है कि ऐप्लिकेशन दूसरे प्रदर्शन पर काम नहीं करे."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"दूसरे प्रदर्शन पर यह ऐप्लिकेशन लॉन्च नहीं हो सकता."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"सेटिंग खोलें."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"त्वरित सेटिंग खोलें."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"त्वरित सेटिंग बंद करें."</string>
@@ -762,6 +762,6 @@
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> तक"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"रखें"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"बदलें"</string>
-    <string name="running_foreground_services_title" msgid="381024150898615683">"ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा उपयोग के विवरण पाने के लिए टैप करें"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"बैकग्राउंड में चल रहे ऐप्लिकेशन"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा उपयोग के विवरण देखने के लिए टैप करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index d99beae..2b6bceb 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -243,7 +243,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci pauzirani"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="6801382439018099779">"Mobilni su podaci pauzirani"</string>
     <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Podaci su pauzirani"</string>
-    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli ste ograničenje podatkovnog prometa koje ste postavili. Više ne upotrebljavate mobilne podatke.\n\nAko nastavite, potrošnja podataka možda će se dodatno naplatiti."</string>
+    <string name="data_usage_disabled_dialog" msgid="4919541636934603816">"Dostigli ste postavljeno ograničenje za podatkovni promet. Više ne upotrebljavate mobilni podatkovni promet.\n\nAko nastavite, moguća je naplata za potrošeni podatkovni promet."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internetske veze"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
@@ -767,5 +767,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Izvođenje aplikacija u pozadini"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podataka"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a29dc24..dd231b7 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Az alkalmazás nem támogatja a másodlagos kijelzőn történő indítást."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Beállítások megnyitása."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Gyorsbeállítások megnyitása."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Gyorsbeállítások bezárása"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Megtartás"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Csere"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"A háttérben még futnak alkalmazások"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Az akkumulátor töltöttségének és az adathasználat részleteinek megtekintéséhez koppintson"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 2b0cba2..0ef1fcf 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -235,7 +235,7 @@
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Աշխատանքային ռեժիմն անջատվեց:"</string>
     <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Աշխատանքային ռեժիմը միացվեց:"</string>
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Տվյալների խնայումն անջատվեց:"</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Տվյալների խնայումը միացվեց:"</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Թրաֆիկի տնտեսումը միացվեց:"</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ցուցադրել պայծառությունը"</string>
     <string name="accessibility_ambient_display_charging" msgid="9084521679384069087">"Լիցքավորում"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2Գ-3Գ տվյալների օգտագործումը դադարեցված է"</string>
@@ -630,8 +630,8 @@
     <string name="headset" msgid="4534219457597457353">"Ականջակալ"</string>
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Ականջակալը կապակցված է"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Ականջակալը կապակցված է"</string>
-    <string name="data_saver" msgid="5037565123367048522">"Թրաֆիկի խնայում"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Տվյալների խնայումը միացված է"</string>
+    <string name="data_saver" msgid="5037565123367048522">"Թրաֆիկի տնտեսում"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Թրաֆիկի տնտեսումը միացված է"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Տվյալների խնայումն անջատված է"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"Միացնել"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"Անջատել"</string>
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> ծանուցում՝ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում:"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Հավելվածը չի կարող աշխատել երկրորդական էկրանի վրա։"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Հավելվածը չի աջակցում երկրորդական էկրանների վրա գործարկումը։"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Բացել կարգավորումները:"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Բացել արագ կարգավորումները:"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Փակել արագ կարգավորումները:"</string>
@@ -734,7 +734,7 @@
     <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"Աջ դյուրանցում"</string>
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"Ձախ դյուրանցումը նաև ապակողպում է"</string>
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"Աջ դյուրանցումը նաև ապակողպում է"</string>
-    <string name="lockscreen_none" msgid="4783896034844841821">"Ոչ մի"</string>
+    <string name="lockscreen_none" msgid="4783896034844841821">"Չկա"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"Գործարկել <xliff:g id="APP">%1$s</xliff:g> հավելվածը"</string>
     <string name="tuner_other_apps" msgid="4726596850501162493">"Այլ հավելվածներ"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"Օղակ"</string>
@@ -762,6 +762,6 @@
     <string name="qs_dnd_until" msgid="3469471136280079874">"Մինչև <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Պահել"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Փոխարինել"</string>
-    <string name="running_foreground_services_title" msgid="381024150898615683">"Հետին ֆոնին գործարկվող հավելվածներ"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Հպել՝ մարտկոցի և տվյալների օգտագործման մասին մանրամասներ ստանալու համար"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Ֆոնային ռեժիմում աշխատող հավելվածներ"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Հպեք՝ մարտկոցի և թրաֆիկի մանրամասները տեսնելու համար"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 756acc6..f7e3054 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -79,7 +79,7 @@
     <string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Pasang sebagai kamera (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang apl Transfer File Android untuk Mac"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Instal apl Transfer File Android untuk Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"Utama"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
@@ -358,7 +358,7 @@
     <string name="zen_silence_introduction" msgid="3137882381093271568">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifikasi kurang darurat di bawah"</string>
-    <string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string>
+    <string name="notification_tap_again" msgid="7590196980943943842">"Tap lagi untuk membuka"</string>
     <string name="keyguard_unlock" msgid="8043466894212841998">"Gesek ke atas untuk membuka kunci"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Perangkat ini dikelola oleh organisasi"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Perangkat ini dikelola oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikasi yang sedang berjalan di latar belakang"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail baterai dan penggunaan data"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail penggunaan baterai dan data"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8cac14d..f009a14 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -393,7 +393,7 @@
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"הסר"</string>
     <string name="guest_wipe_session_title" msgid="6419439912885956132">"שמחים לראותך שוב!"</string>
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"האם ברצונך להמשיך בפעילות באתר?"</string>
-    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"התחל מחדש"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"ברצוני להתחיל מחדש"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"כן, המשך"</string>
     <string name="guest_notification_title" msgid="1585278533840603063">"משתמש אורח"</string>
     <string name="guest_notification_text" msgid="335747957734796689">"הסר את המשתמש האורח כדי למחוק אפליקציות ונתונים"</string>
@@ -730,8 +730,8 @@
     <string name="pip_notification_message" msgid="4171698133469539591">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, הקש כדי לפתוח את ההגדרות ולכבות את התכונה."</string>
     <string name="pip_play" msgid="1417176722760265888">"הפעל"</string>
     <string name="pip_pause" msgid="8881063404466476571">"השהה"</string>
-    <string name="pip_skip_to_next" msgid="1948440006726306284">"דלג אל הבא"</string>
-    <string name="pip_skip_to_prev" msgid="1955311326688637914">"דלג אל הקודם"</string>
+    <string name="pip_skip_to_next" msgid="1948440006726306284">"ברצוני לדלג אל הבא"</string>
+    <string name="pip_skip_to_prev" msgid="1955311326688637914">"ברצוני לדלג אל הקודם"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"הטלפון כבה עקב התחממות"</string>
     <string name="thermal_shutdown_message" msgid="9006456746902370523">"הטלפון פועל כרגיל עכשיו"</string>
     <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n	• תשתמש באפליקציות עתירות משאבים (כגון משחקים, אפליקציות וידאו או אפליקציות ניווט)\n	• תוריד או תעלה קבצים גדולים\n	• תשתמש בטלפון בטמפרטורות גבוהות"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index ea84748..9f63e38 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -702,8 +702,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> の通知: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"アプリは分割画面では動作しないことがあります。"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"アプリで分割画面がサポートされていません。"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"アプリは 2 次画面では動作しないことがあります。"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"アプリは 2 次画面での起動に対応していません"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"設定を開きます。"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"クイック設定を開きます。"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"クイック設定を閉じます。"</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"設定を維持"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"設定を変更"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"バックグラウンドで実行中のアプリ"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"タップで電池やデータの使用量の詳細を確認"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"タップして電池やデータの使用量を確認"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index ae50bd9..3bb07cd 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"მეორეულ ეკრანზე გაშვება მხარდაუჭერელია აპის მიერ."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"პარამეტრების გახსნა."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"სწრაფი პარამეტრების გახსნა."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"სწრაფი პარამეტრების დახურვა."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 8b891bb..44d7bd8 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Қалсын"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ауыстыру"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Фонда жұмыс істеп тұрған қолданбалар"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батарея мен деректер трафигі туралы мәліметтер алу үшін түртіңіз"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батарея мен деректер трафигі туралы білу үшін түртіңіз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 3f7bd53..b9aaaeb 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -298,7 +298,7 @@
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"វ៉ាយហ្វាយ​បានបិទ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi បានបើក"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"គ្មានបណ្តាញ Wi-Fi ទេ"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ខាស"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ភ្ជាប់"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ការ​ចាត់​ថ្នាក់"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ឧបករណ៍​​ដែល​មិន​មាន​ឈ្មោះ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ត្រៀម​រួចរាល់​ដើម្បី​ចាត់​ថ្នាក់"</string>
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"កម្មវិធីអាចនឹងមិនដំណើរការនៅលើអេក្រង់បំបែកទេ"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"កម្មវិធីនេះ​ប្រហែល​ជាមិនដំណើរការ​នៅលើ​អេក្រង់បន្ទាប់បន្សំទេ។"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"កម្មវិធី​នេះមិន​អាច​ចាប់ផ្តើម​បានទេ ដោយសារ​អេក្រង់បន្ទាប់បន្សំមិនស្គាល់វា។"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"កម្មវិធី​នេះមិន​អាច​ចាប់ផ្តើម​នៅលើ​អេក្រង់បន្ទាប់បន្សំបានទេ។"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"បើកការកំណត់"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"បើកការកំណត់រហ័ស"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"បិទការកំណត់រហ័ស"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"រក្សានៅ​ដដែល"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ជំនួស"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ចុចដើម្បីទទួលបានព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ថ្ម និងទិន្នន័យ"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ចុចដើម្បីមើលព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ទិន្នន័យ និងថ្ម"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 19fb3af..1d32f91 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ವಿಭಜಿಸಿದ ಪರದೆಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ಎರಡನೇ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ಎರಡನೇ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ಸೆಕೆಂಡರಿ ಡಿಸ್‌ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಮುಚ್ಚಿ."</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"ಇರಿಸಿ"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ಬದಲಿಸಿ"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ಬ್ಯಾಟರಿ ಮತ್ತು ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 95dfeb4..6aa58e6 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"유지"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"바꾸기"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"백그라운드에서 실행 중인 앱"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"탭하여 배터리 및 데이터 사용량에 관한 세부정보 보기"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"탭하여 배터리 및 데이터 사용량 확인"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index c8f0bc7..d737c26 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> эскертмеси: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Колдонмодо экран бөлүнбөшү мүмкүн."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Колдонмодо экран бөлүнбөйт."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Колдонмо көмөкчү дисплейде иштебей калышы мүмкүн."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Колдонмо көмөкчү дисплейлерде иштетилбейт."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Жөндөөлөрдү ачуу."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Ыкчам жөндөөлөрдү ачуу."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Ыкчам жөндөөлөрдү жабуу."</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Ушундай калтыруу"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Алмаштыруу"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Фондо иштеп жаткан колдонмолор"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батареянын кубаты жана Интернеттин колдонулушу жөнүндө билүү үчүн таптап коюңуз"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 198e8f6..4d2010a 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -700,7 +700,7 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"ການແຈ້ງເຕືອນ <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ແອັບອາດຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ເປີດການຕັ້ງຄ່າ."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ເປີດການຕັ້ງຄ່າດ່ວນ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index d83737d..50f6b6b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -709,7 +709,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Programa gali neveikti naudojant skaidytą ekraną."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programoje nepalaikomas skaidytas ekranas."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Programa gali neveikti antriniame ekrane."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Programa nepalaiko pristatymo antriniuose ekranuose."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Programa nepalaiko paleisties antriniuose ekranuose."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Atidaryti nustatymus."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Atidaryti sparčiuosius nustatymus."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Uždaryti sparčiuosius nustatymus."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 56468a3..91f7508 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -35,8 +35,8 @@
     <string name="battery_low_title" msgid="6456385927409742437">"Батеријата е слаба"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"Преостануваат <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Преостануваат <xliff:g id="PERCENTAGE">%s</xliff:g>. Вклучен е штедачот на батерија."</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Полначот на УСБ меморијата не е поддржан.\nКористете го само полначот доставен со уредот."</string>
-    <string name="invalid_charger_title" msgid="3515740382572798460">"Полнењето преку УСБ не е поддржано."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Полначот на USB меморијата не е поддржан.\nКористете го само полначот доставен со уредот."</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Полнењето преку USB не е поддржано."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Користете го само доставениот полнач."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Поставки"</string>
     <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Дали да се вклучи штедачот на батерија?"</string>
@@ -51,20 +51,20 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Поврзан е Bluetooth"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Постави методи на внес."</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физичка тастатура"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Дозволи апликацијата <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи кон УСБ уредот?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Дозволи апликацијата <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи кон УСБ додатокот?"</string>
-    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> кога е поврзан овој УСБ уред?"</string>
-    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> кога е поврзан овој УСБ додаток?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Нема инсталирано апликации што работат со овој УСБ додаток. Дознајте повеќе за овој додаток на <xliff:g id="URL">%1$s</xliff:g>"</string>
-    <string name="title_usb_accessory" msgid="4966265263465181372">"УСБ додаток"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Дозволи апликацијата <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи кон USB уредот?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Дозволи апликацијата <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапи кон USB додатокот?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> кога е поврзан овој USB уред?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> кога е поврзан овој USB додаток?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Нема инсталирано апликации што работат со овој USB додаток. Дознајте повеќе за овој додаток на <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB додаток"</string>
     <string name="label_view" msgid="6304565553218192990">"Прикажи"</string>
-    <string name="always_use_device" msgid="1450287437017315906">"Користи го стандардно за овој УСБ уред"</string>
-    <string name="always_use_accessory" msgid="1210954576979621596">"Користи го стандардно за овој приклучок за УСБ"</string>
-    <string name="usb_debugging_title" msgid="4513918393387141949">"Овозможи отстранување грешки на УСБ?"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Користи го стандардно за овој USB уред"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Користи го стандардно за овој приклучок за USB"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Овозможи отстранување грешки на USB?"</string>
     <string name="usb_debugging_message" msgid="2220143855912376496">"Клучниот отпечаток на RSA на компјутерот е:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Секогаш дозволувај од овој компјутер"</string>
-    <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстранувањето грешки на УСБ не е дозволено"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки на УСБ. За да ја користите функцијата, префрлете се на корисникот Администратор."</string>
+    <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстранувањето грешки на USB не е дозволено"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки на USB. За да ја користите функцијата, префрлете се на корисникот Администратор."</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Зумирај да се исполни екранот"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растегни да се исполни екранот"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Сликата на екранот се зачувува..."</string>
@@ -76,7 +76,7 @@
     <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Се појави проблем при зачувување на сликата од екранот."</string>
     <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Сликата од екранот не може да се зачува поради ограничена меморија."</string>
     <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Апликацијата или вашата организација не дозволува снимање слики од екранот"</string>
-    <string name="usb_preference_title" msgid="6551050377388882787">"Пренос на датотека со УСБ"</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"Пренос на датотека со USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Монтирај како мултимедијален плеер (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Монтирај како фотоапарат (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Инсталирај Android апл. „Пренос на датот.“ за Mac"</string>
@@ -151,14 +151,14 @@
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Роаминг"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
-    <string name="accessibility_no_sim" msgid="8274017118472455155">"Нема СИМ картичка."</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"Нема SIM картичка."</string>
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Мобилен интернет"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Мобилниот интернет е вклучен"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"Мобилниот интернет е исклучен"</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Се поврзува со Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим на работа во авион."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN е вклучена."</string>
-    <string name="accessibility_no_sims" msgid="3957997018324995781">"Нема СИМ-картичка"</string>
+    <string name="accessibility_no_sims" msgid="3957997018324995781">"Нема SIM-картичка"</string>
     <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Променување на мрежата на операторот."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отвори ги деталите за батеријата"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Известување од <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Апликацијата можеби нема да работи во поделен екран."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Апликацијата не поддржува поделен екран."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Аппликацијата може да не функционира на второстепен екран."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Апликацијата не поддржува стартување на второстепени екрани."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Апликацијата може да не функционира на друг екран."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Апликацијата не поддржува стартување на други екрани."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Отворете ги поставките."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Отворете ги брзите поставки."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Затворете ги брзите поставки."</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 606b925..7def7a5 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -346,7 +346,7 @@
   </string-array>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ചാർജായി"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"ചാർജ്ജുചെയ്യുന്നു"</string>
-    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"ഫുൾ ചാർജാകാൻ, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"നെറ്റ്‌വർക്ക്\nനിരീക്ഷിക്കപ്പെടാം"</string>
     <string name="description_target_search" msgid="3091587249776033139">"തിരയൽ"</string>
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"സ്പ്ലിറ്റ്-സ്ക്രീനിനൊപ്പം ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"രണ്ടാം ഡിസ്‌പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"രണ്ടാം ഡിസ്‌പ്ലേകളിൽ സമാരംഭിക്കുന്നത് ആപ്പ് അനുവദിക്കുന്നില്ല."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"രണ്ടാം ഡിസ്‌പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ക്രമീകരണം തുറക്കുക."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"ദ്രുത ക്രമീകരണം തുറക്കുക."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"ദ്രുത ക്രമീകരണം അടയ്ക്കുക."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index e1d9099..fcc7903 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -530,7 +530,7 @@
     <string name="tuner_toast" msgid="603429811084428439">"Баяр хүргэе! Системийн UI Tохируулагчийг тохиргоонд нэмлээ"</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Тохиргооноос устгах"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Системийн UI Тохируулагчийг тохиргооноос устгаж, үүнтэй холбоотой бүх тохиргоог ашиглахаа болих уу?"</string>
-    <string name="activity_not_found" msgid="348423244327799974">"Апп-ыг таны төхөөрөмжид суулгаагүй байна"</string>
+    <string name="activity_not_found" msgid="348423244327799974">"Аппыг таны төхөөрөмжид суулгаагүй байна"</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Цагийн секундыг харуулах"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Статус талбарт цагийн секундыг харуулах. Энэ нь тэжээлийн цэнэгт нөлөөлж болно."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Түргэн тохиргоог дахин засварлах"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Хадгалах"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Солих"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Цаана ажиллаж буй апп"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батерей, дата ашиглалтын талаар дэлгэрэнгүй мэдээллийг харахын тулд товшино уу"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 634f8f7..8ded3da 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"दुय्यम डिस्प्लेवर अ‍ॅप कदाचित चालणार नाही."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"दुय्यम डिस्प्लेंवर अ‍ॅप लाँचचे समर्थन करत नाही."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"दुसऱ्या डिस्प्लेवर अ‍ॅप कदाचित चालणार नाही."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"दुसऱ्या डिस्प्लेवर अ‍ॅप लाँच होणार नाही."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"सेटिंग्ज उघडा."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"जलद सेटिंग्ज उघडा."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"जलद सेटिंग्ज बंद करा."</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 480293c..fe5a0e0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"မိုဘိုင်းဒေတာ"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"မိုဘိုင်းဒေတာကို ဖွင့်ထားပါသည်"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"မိုဘိုင်းဒေတာကို ပိတ်ထားပါသည်"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ဘလူးတုသ်ဖြင့်ကွန်ရက်ချိတ်ခြင်း"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ဘလူးတုသ်သုံး၍ ချိတ်ဆက်ခြင်း"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်။"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN ကို ဖွင့်ထားသည်။"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"SIM ကဒ် မရှိပါ"</string>
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> အကြောင်းကြားချက် − <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"မျက်နှာပြင် ခွဲခြမ်းပြသမှုဖြင့် အက်ပ်သည် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်မျက်နှာပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်မျက်နှာပြင်ပေါ်တွင် ဖွင့်ပြရန်အတွက် ပံ့ပိုးမထားပါ။"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ဆက်တင်များကို ဖွင့်ပါ။"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"အမြန်ဆက်တင်များကို ဖွင့်ပါ။"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"အမြန်ဆက်တင်များကို ပိတ်ပါ။"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ab31f82..585ae77 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -50,7 +50,7 @@
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"सूचनाहरू"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"ब्लुटुथ टेथर भयो"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
-    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"फिजिकल किबोर्ड"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"वास्तविक किबोर्ड"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> USB उपकरणलाई पहुँच दिनको लागि अनुप्रयोगलाई अनुमति दिने हो?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> USB पाटपुर्जालाई पहुँच दिनको लागि अनुप्रयोगलाई अनुमति दिने हो?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"यो USB उपकरण जोडिएको बेला <xliff:g id="ACTIVITY">%1$s</xliff:g> खोल्ने हो?"</string>
@@ -631,7 +631,7 @@
     <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"हेडफोनहरू जडान गरियो"</string>
     <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"हेडसेट जडान गरियो"</string>
     <string name="data_saver" msgid="5037565123367048522">"डेटा सेभर"</string>
-    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"डेटा सेभर अन छ"</string>
+    <string name="accessibility_data_saver_on" msgid="8454111686783887148">"डेटा सेभर सक्रिय छ"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"डेटा सेभर बन्द छ"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"सक्रिय गर्नुहोस्"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"निष्क्रिय"</string>
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"अनुप्रयोगले विभाजित-स्क्रिनमा काम नगर्न सक्छ।"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"यो अनुप्रयोगले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लोकार्पण गर्ने गतिविधिलाई समर्थन गर्दैन।"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"सेटिङहरूलाई खोल्नुहोस्।"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"द्रुत सेटिङहरूलाई खोल्नुहोस्।"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"द्रुत सेटिङहरूलाई बन्द गर्नुहोस्।"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"राख्नुहोस्"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"प्रतिस्थापन गर्नुहोस्"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ब्याट्री र डेटा प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"ब्याट्री र डेटाका प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 856f172..d9de896 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -34,14 +34,14 @@
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"Accu is bijna leeg"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> resterend"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> resterend. Accubesparing is ingeschakeld."</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> resterend. Batterijbesparing is ingeschakeld."</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund.\nGebruik alleen de bijgeleverde oplader."</string>
     <string name="invalid_charger_title" msgid="3515740382572798460">"Opladen via USB wordt niet ondersteund."</string>
     <string name="invalid_charger_text" msgid="5474997287953892710">"Gebruik alleen de bijgeleverde oplader."</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Instellingen"</string>
-    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Accubesparing inschakelen?"</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Batterijbesparing inschakelen?"</string>
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Inschakelen"</string>
-    <string name="battery_saver_start_action" msgid="5576697451677486320">"Accubesparing inschakelen"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"Batterijbesparing inschakelen"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellingen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Scherm automatisch draaien"</string>
@@ -402,9 +402,9 @@
     <string name="user_remove_user_title" msgid="4681256956076895559">"Gebruiker verwijderen?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"Alle apps en gegevens van deze gebruiker worden verwijderd."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Verwijderen"</string>
-    <string name="battery_saver_notification_title" msgid="237918726750955859">"Accubesparing is ingeschakeld"</string>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Batterijbesparing is ingeschakeld"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Vermindert de prestaties en achtergrondgegevens"</string>
-    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Accubesparing uitschakelen"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Batterijbesparing uitschakelen"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gaat alles vastleggen dat wordt weergegeven op je scherm."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Niet opnieuw weergeven"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alles wissen"</string>
@@ -576,7 +576,7 @@
     <string name="snooze_undo" msgid="6074877317002985129">"ONGEDAAN MAKEN"</string>
     <string name="snoozed_for_time" msgid="2390718332980204462">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
-    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Accubesparing niet beschikbaar tijdens opladen"</string>
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterijbesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterijbesparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
     <string name="keyboard_key_button_template" msgid="6230056639734377300">"Knop <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"App werkt mogelijk niet met gesplitst scherm."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"App biedt geen ondersteuning voor gesplitst scherm."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"App werkt mogelijk niet op een secundair display."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"App biedt geen ondersteuning voor lancering op secundaire displays."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"App kan niet op secundaire displays worden gestart."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Instellingen openen."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Snelle instellingen openen."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Snelle instellingen sluiten."</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Behouden"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Vervangen"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Apps uitgevoerd op achtergrond"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik voor informatie over batterij- en datagebruik"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik voor batterij- en datagebruik"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0a65637..9c54aff 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -44,7 +44,7 @@
     <string name="battery_saver_start_action" msgid="5576697451677486320">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
-    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"ਆਟੋ-ਰੋਟੇਟ ਸਕ੍ਰੀਨ"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"ਸਕ੍ਰੀਨ ਆਪਣੇ-ਆਪ ਘੁੰਮਾਓ"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"ਮਿਊਟ ਕਰੋ"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ਆਟੋ"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"ਸੂਚਨਾਵਾਂ"</string>
@@ -58,8 +58,8 @@
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ਕੋਈ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਇਸ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕੰਮ ਨਹੀਂ ਕਰਦੇ। <xliff:g id="URL">%1$s</xliff:g> ਤੇ ਇਸ ਐਕਸੈਸਰੀ ਬਾਰੇ ਹੋਰ ਜਾਣੋ"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"USB ਐਕਸੈਸਰੀ"</string>
     <string name="label_view" msgid="6304565553218192990">"ਦੇਖੋ"</string>
-    <string name="always_use_device" msgid="1450287437017315906">"ਇਸ USB ਡੀਵਾਈਸ ਲਈ ਬਾਇ ਡਿਫੌਲਟ ਵਰਤੋ"</string>
-    <string name="always_use_accessory" msgid="1210954576979621596">"ਇਸ USB ਐਕਸਸੈਰੀ ਲਈ ਬਾਇ ਡਿਫੌਲਟ ਵਰਤੋ"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"ਇਸ USB ਡੀਵਾਈਸ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"ਇਸ USB ਐਕਸਸੈਰੀ ਲਈ ਬਾਇ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਰਤੋ"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"ਕੀ USB ਡੀਬਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
     <string name="usb_debugging_message" msgid="2220143855912376496">"ਕੰਪਿਊਟਰ ਦਾ RSA ਕੁੰਜੀ ਫਿੰਗਰਪ੍ਰਿੰਟ ਹੈ:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"ਹਮੇਸ਼ਾਂ ਇਸ ਕੰਪਿਊਟਰ ਤੋਂ ਆਗਿਆ ਦਿਓ"</string>
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"ਮੋਬਾਈਲ ਡੈਟਾ"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"ਮੋਬਾਈਲ ਡੈਟਾ ਚਾਲੂ ਹੈ"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"ਮੋਬਾਈਲ ਡੈਟਾ ਬੰਦ ਹੈ"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth ਟੀਥਰਿੰਗ।"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth ਟੈਦਰਿੰਗ।"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"ਏਅਰਪਲੇਨ ਮੋਡ।"</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN ਚਾਲੂ ਹੈ।"</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"ਕੋਈ SIM ਕਾਰਡ ਨਹੀਂ।"</string>
@@ -269,11 +269,11 @@
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ਕੇਵਲ ਤਰਜੀਹੀ"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ਕੇਵਲ ਅਲਾਰਮ"</string>
-    <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ਕੁਲ ਚੁੱਪੀ"</string>
+    <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ਸੰਪੂਰਨ ਖਾਮੋਸ਼ੀ"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> ਡਿਵਾਈਸਾਂ)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth ਬੰਦ"</string>
-    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ਕੋਈ ਪੇਅਰ ਕੀਤੀਆਂ ਡਿਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ਕੋਈ ਜੋੜਾਬੱਧ ਕੀਤੀਆਂ ਡੀਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"ਚਮਕ"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"ਆਟੋ-ਰੋਟੇਟ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
@@ -291,14 +291,14 @@
     <string name="quick_settings_time_label" msgid="4635969182239736408">"ਸਮਾਂ"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"ਮੈਂ"</string>
     <string name="quick_settings_user_title" msgid="4467690427642392403">"ਵਰਤੋਂਕਾਰ"</string>
-    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"ਨਵਾਂ ਉਪਭੋਗਤਾ"</string>
+    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ਕੋਈ ਨੈੱਟਵਰਕ ਨਹੀਂ"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ਬੰਦ"</string>
     <string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi ਚਾਲੂ"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ਕੋਈ Wi-Fi ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ"</string>
-    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ਪ੍ਰਸਾਰਿਤ ਕਰੋ"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"ਕਾਸਟ"</string>
     <string name="quick_settings_casting" msgid="6601710681033353316">"ਕਾਸਟਿੰਗ"</string>
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤੀ ਡੀਵਾਈਸ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ਜੋੜਨ ਲਈ ਤਿਆਰ"</string>
@@ -334,7 +334,7 @@
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ਖੋਜੋ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਸੁਰੱਖਿਅਤ-ਮੋਡ ਵਿੱਚ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।"</string>
-    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ਸਭ ਸਾਫ਼ ਕਰੋ"</string>
+    <string name="recents_stack_action_button_label" msgid="6593727103310426253">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="recents_drag_hint_message" msgid="2649739267073203985">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ਵਰਟੀਕਲ ਸਪਲਿਟ"</string>
@@ -352,9 +352,9 @@
     <string name="description_target_search" msgid="3091587249776033139">"ਖੋਜੋ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਲਈ ਉੱਪਰ ਸਲਾਈਡ ਕਰੋ।"</string>
     <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string>
-    <string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਨਿਰਦਿਸ਼ਟ ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਇਵੈਂਟਸ, ਅਤੇ ਕਾਲਰਸ ਤੋਂ ਇਲਾਵਾ, ਧੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਤੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਤੈਅ ਕੀਤੇ ਅਲਾਰਮਾਂ, ਯਾਦ-ਦਹਾਨੀਆਂ, ਵਰਤਾਰਿਆਂ, ਅਤੇ ਕਾਲ ਕਰਨ ਵਾਲਿਆਂ ਨੂੰ ਛੱਡਕੇ, ਤੁਹਾਨੂੰ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟਾਂ ਵੱਲੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
-    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ।"</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓ, ਅਤੇ ਗੇਮਾਂ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਥਰਥਰਾਹਟ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਂਗੇ।"</string>
     <string name="zen_silence_introduction" msgid="3137882381093271568">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ।"</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
@@ -366,7 +366,7 @@
     <string name="voice_hint" msgid="8939888732119726665">"ਵੌਇਸ ਅਸਿਸਟ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="camera_hint" msgid="7939688436797157483">"ਕੈਮਰੇ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"ਕੁੱਲ ਸਾਈਲੈਂਟ। ਇਹ ਸਕ੍ਰੀਨ ਰੀਡਰਾਂ ਨੂੰ ਵੀ ਸਾਈਲੈਂਸ ਕਰ ਦੇਵੇਗਾ।"</string>
-    <string name="interruption_level_none" msgid="6000083681244492992">"ਕੁਲ ਚੁੱਪੀ"</string>
+    <string name="interruption_level_none" msgid="6000083681244492992">"ਸੰਪੂਰਨ ਖਾਮੋਸ਼ੀ"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"ਕੇਵਲ ਤਰਜੀਹੀ"</string>
     <string name="interruption_level_alarms" msgid="5226306993448328896">"ਕੇਵਲ ਅਲਾਰਮ"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ਕੁਲ \n ਚੁੱਪੀ"</string>
@@ -380,7 +380,7 @@
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ਪ੍ਰੋਫਾਈਲ ਦਿਖਾਓ"</string>
     <string name="user_add_user" msgid="5110251524486079492">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰੋ"</string>
-    <string name="user_new_user_name" msgid="426540612051178753">"ਨਵਾਂ ਉਪਭੋਗਤਾ"</string>
+    <string name="user_new_user_name" msgid="426540612051178753">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string>
     <string name="guest_nickname" msgid="8059989128963789678">"ਮਹਿਮਾਨ"</string>
     <string name="guest_new_guest" msgid="600537543078847803">"ਮਹਿਮਾਨ ਜੋੜੋ"</string>
     <string name="guest_exit_guest" msgid="7187359342030096885">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
@@ -407,7 +407,7 @@
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"ਬੈਟਰੀ ਸੇਵਰ ਬੰਦ ਕਰੋ"</string>
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਉਹ ਸਭ ਕੁਝ ਕੈਪਚਰ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰ ਦੇਵੇਗਾ, ਜੋ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਤੇ ਡਿਸਪਲੇ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
-    <string name="clear_all_notifications_text" msgid="814192889771462828">"ਸਭ ਸਾਫ਼ ਕਰੋ"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
@@ -611,7 +611,7 @@
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ਪਿੱਛੇ"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ਵਾਪਸ ਇਨਪੁੱਟ ਵਿਧੀ \'ਤੇ ਬਦਲੋ"</string>
+    <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ਇਨਪੁੱਟ ਵਿਧੀ ਬਦਲੋ"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ਐਪਲੀਕੇਸ਼ਨਾਂ"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ਸਹਾਇਕ"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ਬ੍ਰਾਊਜ਼ਰ"</string>
@@ -762,6 +762,6 @@
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> ਤੱਕ"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"ਰੱਖੋ"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"ਬਦਲੋ"</string>
-    <string name="running_foreground_services_title" msgid="381024150898615683">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਐਪਾਂ"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b3ccfc6..c23d0d0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -708,8 +708,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Powiadomienie z aplikacji <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Aplikacja może nie działać przy podzielonym ekranie."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacja nie obsługuje dzielonego ekranu."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacja może nie działać na ekranie dodatkowym."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacja nie obsługuje uruchamiania na ekranach dodatkowych."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Aplikacja może nie działać na dodatkowym ekranie."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Otwórz ustawienia."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Otwórz szybkie ustawienia."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Zamknij szybkie ustawienia."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 1089fcf..4e712d7 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -269,7 +269,7 @@
     <string name="start_dreams" msgid="5640361424498338327">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não perturbe"</string>
-    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Só prioridade"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Somente prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Somente alarmes"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silêncio total"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
@@ -369,7 +369,7 @@
     <string name="camera_hint" msgid="7939688436797157483">"Deslize a partir do ícone da câmera"</string>
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Silêncio total. Isso também silenciará os leitores de tela."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Silêncio total"</string>
-    <string name="interruption_level_priority" msgid="6426766465363855505">"Só prioridade"</string>
+    <string name="interruption_level_priority" msgid="6426766465363855505">"Somente prioridade"</string>
     <string name="interruption_level_alarms" msgid="5226306993448328896">"Somente alarmes"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 9c03091..5db30bb 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -387,7 +387,7 @@
     <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Pretende remover o convidado?"</string>
     <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Todas as aplicações e dados desta sessão serão eliminados."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Remover"</string>
-    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Bem-vindo(a) de volta, caro(a) convidado(a)!"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Bem-vindo de volta, caro(a) convidado(a)!"</string>
     <string name="guest_wipe_session_message" msgid="8476238178270112811">"Pretende continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Sim, continuar"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 1089fcf..4e712d7 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -269,7 +269,7 @@
     <string name="start_dreams" msgid="5640361424498338327">"Protetor de tela"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não perturbe"</string>
-    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Só prioridade"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Somente prioridade"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Somente alarmes"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silêncio total"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
@@ -369,7 +369,7 @@
     <string name="camera_hint" msgid="7939688436797157483">"Deslize a partir do ícone da câmera"</string>
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Silêncio total. Isso também silenciará os leitores de tela."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Silêncio total"</string>
-    <string name="interruption_level_priority" msgid="6426766465363855505">"Só prioridade"</string>
+    <string name="interruption_level_priority" msgid="6426766465363855505">"Somente prioridade"</string>
     <string name="interruption_level_alarms" msgid="5226306993448328896">"Somente alarmes"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6ac077b..bf87937 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -639,7 +639,7 @@
     <string name="data_saver" msgid="5037565123367048522">"Economizor de date"</string>
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Economizorul de date este activat"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Economizorul de date este dezactivat"</string>
-    <string name="switch_bar_on" msgid="1142437840752794229">"Activați"</string>
+    <string name="switch_bar_on" msgid="1142437840752794229">"Activat"</string>
     <string name="switch_bar_off" msgid="8803270596930432874">"Dezactivați"</string>
     <string name="nav_bar" msgid="1993221402773877607">"Bară de navigare"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"Aspect"</string>
@@ -706,8 +706,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Notificare <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplicația nu acceptă ecranul împărțit."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Este posibil ca aplicația să nu funcționeze pe un afișaj secundar."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplicația nu acceptă lansare pe afișaje secundare."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Aplicația nu acceptă lansare pe ecrane secundare."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Deschideți setările."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Deschideți setările rapide."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Închideți setările rapide."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 724263c..09e1bcb 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -710,8 +710,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Уведомление <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Приложение не поддерживает разделение экрана."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Приложение не поддерживает разделение экрана."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Приложение может не работать на дополнительном экране."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Приложение не поддерживает запуск на дополнительных экранах."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Приложение может не работать на дополнительном экране"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Приложение не поддерживает запуск на дополнительных экранах"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Открыть настройки."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Развернуть быстрые настройки."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Скрыть быстрые настройки."</string>
@@ -773,5 +773,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Сохранить"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Заменить"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работающие в фоновом режиме"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Нажмите, чтобы увидеть данные об энергопотреблении и объеме трафика"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Нажмите, чтобы проверить энергопотребление и трафик"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index b8c5737..c54ce53 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Mbaj"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Zëvendëso"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacionet që ekzekutohen në sfond"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trokit për detaje për baterinë dhe përdorimin e të dhënave"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trokit për detaje mbi baterinë dhe përdorimin e të dhënave"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f4ee432..e9445ff 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -767,5 +767,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Задржи"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замени"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Апликације покренуте у позадини"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Додирните да бисте прегледали детаље о батерији и потрошњи података"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Додирните за детаље о батерији и потрошњи података"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index d572645..286eba3 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -701,7 +701,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Programu haiwezi kutumia skrini iliyogawanywa."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Huenda programu isifanye kazi kwenye dirisha lingine."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Programu haiwezi kutumia kipengele cha kuonyesha kwenye madirisha mengine."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Fungua mipangilio."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Fungua mipangilio ya haraka."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Funga mipangilio ya haraka."</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 6f014af..6300d8c 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -700,7 +700,7 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"திரைப் பிரிப்பில் பயன்பாடு வேலைசெய்யாமல் போகக்கூடும்."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"திரையைப் பிரிப்பதைப் பயன்பாடு ஆதரிக்கவில்லை."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"இரண்டாம்நிலைத் திரையில் பயன்பாடுகள் வேலை செய்யாமல் போகக்கூடும்."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"இரண்டாம்நிலைத் திரையில் பயன்பாடு வேலை செய்யாமல் போகக்கூடும்."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"அமைப்புகளைத் திற."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"விரைவு அமைப்புகளைத் திற."</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"வைத்திரு"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"மாற்று"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் தரவு உபயோகம் குறித்த விவரங்களுக்கு, தட்டவும்"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் தரவு உபயோக விவரங்களைக் காண, தட்டவும்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 7d5d769..3900f26 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> నోటిఫికేషన్: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"స్క్రీన్ విభజనతో అనువర్తనం పని చేయకపోవచ్చు."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ప్రత్యామ్నాయ ప్రదర్శనపై ఆప్ పని చేయకపోవచ్చు."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ప్రత్యామ్నాయ ప్రదర్శనలపై ప్రారంభానికి ఆప్ మద్దతు లేదు."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ప్రత్యామ్నాయ డిస్‌ప్లేలో యాప్ పని చేయకపోవచ్చు."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ప్రత్యామ్నాయ డిస్‌ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"సెట్టింగ్‌లను తెరవండి."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"శీఘ్ర సెట్టింగ్‌లను తెరవండి."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"శీఘ్ర సెట్టింగ్‌లను మూసివేయండి."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index dff3481..7baae25 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -762,6 +762,6 @@
     <string name="qs_dnd_until" msgid="3469471136280079874">"Bitiş: <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Koru"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Değiştir"</string>
-    <string name="running_foreground_services_title" msgid="381024150898615683">"Uygulamalar arka planda çalışıyor"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Arka planda çalışan uygulamalar"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 2119c40..54decf9 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -710,8 +710,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"Сповіщення <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Додаток може не працювати в режимі розділеного екрана."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Додаток не підтримує розділення екрана."</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Додаток може не працювати на додатковому дисплеї."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Додаток не підтримує запуск на додаткових дисплеях."</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Додаток може не працювати на додатковому екрані."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Додаток не підтримує запуск на додаткових екранах."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Відкрити налаштування."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Відкрити швидкі налаштування."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Закрити швидкі налаштування."</string>
@@ -773,5 +773,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Залишити"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Замінити"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Додатки, які працюють у фоновому режимі"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Торкніться, щоб переглянути інформацію про використання заряду акумулятора та даних"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Торкніться, щоб перевірити використання акумулятора й трафік"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index e47ccb6..06e99a1 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> اطلاع: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ممکن ہے کہ ایپ سپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"یہ ایپ شاید ثانوی ڈسپلے پر کام نہ کرے۔"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"یہ ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی ہے۔"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"ترتیبات کھولیں۔"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"فوری ترتیبات کھولیں۔"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"فوری ترتیبات بند کریں۔"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 2e39189..658aeea 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -703,7 +703,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"Ilova ekranni ikkiga bo‘lish rejimini qo‘llab-quvvatlamaydi."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Bu ilova qo‘shimcha ekranlarda ishlamaydi."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Sozlamalarni ochish."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Tezkor sozlamalarni ochish."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Tezkor sozlamalarni yopish."</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Saqlab qolish"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Almashtirish"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Fonda ishlayotgan ilovalar"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya va trafik sarfiga oid tafsilotlarni olish uchun ustiga bosing"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya va trafik sarfi tafsilotlari uchun ustiga bosing"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 347317e..e4959fe 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -155,7 +155,7 @@
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Dữ liệu di động"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Dữ liệu di động đang bật"</string>
     <string name="accessibility_cell_data_off" msgid="443267573897409704">"Dữ liệu di động đang tắt"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Truy cập Internet qua Bluetooth."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Chia sẻ kết nối Internet qua Bluetooth"</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Chế độ trên máy bay."</string>
     <string name="accessibility_vpn_on" msgid="5993385083262856059">"VPN đang bật."</string>
     <string name="accessibility_no_sims" msgid="3957997018324995781">"Không có thẻ SIM nào."</string>
@@ -765,5 +765,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Giữ"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Thay thế"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Ứng dụng đang chạy trong nền"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Nhấn để biết chi tiết về pin và mức sử dụng dữ liệu"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0ad9bfe..96c81c0 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g>通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"应用可能无法在分屏模式下正常运行。"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"应用不支持分屏。"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"应用可能无法在辅助显示屏上正常运行。"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"应用不支持在辅助显示屏上启动。"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"应用可能无法在辅显示屏上正常运行。"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"应用不支持在辅显示屏上启动。"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"打开设置。"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"开启快捷设置。"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"关闭快捷设置。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e526bb7..af7f769 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -202,7 +202,7 @@
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"飛行模式已開啟。"</string>
     <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"開啟「請勿騷擾」,僅限優先。"</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"開啟「請勿騷擾」,完全靜音。"</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"開啟「請勿騷擾」,僅限鬧鐘。"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"開啟「請勿騷擾」,只限鬧鐘。"</string>
     <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"請勿騷擾。"</string>
     <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"「請勿騷擾」關閉"</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"已關閉「請勿騷擾」。"</string>
@@ -223,7 +223,7 @@
     <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"增加時間。"</string>
     <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"減少時間。"</string>
     <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"閃光燈已關閉。"</string>
-    <string name="accessibility_quick_settings_flashlight_unavailable" msgid="8012811023312280810">"無法使用手電筒。"</string>
+    <string name="accessibility_quick_settings_flashlight_unavailable" msgid="8012811023312280810">"無法使用閃光燈。"</string>
     <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"閃光燈已開啟。"</string>
     <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"閃光燈已關閉。"</string>
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"閃光燈已開啟。"</string>
@@ -270,7 +270,7 @@
     <string name="ethernet_label" msgid="7967563676324087464">"以太網"</string>
     <string name="quick_settings_dnd_label" msgid="8735855737575028208">"請勿騷擾"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"僅限優先"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅限鬧鐘"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"只限鬧鐘"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"完全靜音"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"藍牙"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"藍牙 (<xliff:g id="NUMBER">%d</xliff:g> 部裝置)"</string>
@@ -308,7 +308,7 @@
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"反轉顏色"</string>
-    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
     <string name="quick_settings_more_settings" msgid="326112621462813682">"更多設定"</string>
     <string name="quick_settings_done" msgid="3402999958839153376">"完成"</string>
     <string name="quick_settings_connected" msgid="1722253542984847487">"已連線"</string>
@@ -316,7 +316,7 @@
     <string name="quick_settings_tethering_label" msgid="7153452060448575549">"網絡共享"</string>
     <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"熱點"</string>
     <string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
-    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"手電筒"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"閃光燈"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"流動數據"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"數據用量"</string>
     <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"剩餘資料"</string>
@@ -370,7 +370,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"完全靜音。這亦將使螢幕閱讀器靜音。"</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"完全靜音"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"僅限優先"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"僅限鬧鐘"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"只限鬧鐘"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅限\n優先"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅限\n鬧鐘"</string>
@@ -571,12 +571,12 @@
     <string name="notification_done" msgid="5279426047273930175">"完成"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="notification_menu_gear_description" msgid="2204480013726775108">"通知控制項"</string>
-    <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知重響選項"</string>
+    <string name="notification_menu_snooze_description" msgid="3653669438131034525">"通知延後選項"</string>
     <string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
     <string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
     <string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
-    <string name="snoozed_for_time" msgid="2390718332980204462">"已隔 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>重響"</string>
+    <string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
     <string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
@@ -703,7 +703,7 @@
     <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"應用程式不支援分割畫面。"</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"應用程式可能無法在次要顯示屏上運作。"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"應用程式不支援在次要顯示屏上啟動。"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"應用程式無法在次要顯示屏上啟動。"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"開啟設定。"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"開啟快速設定。"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"關閉快速設定。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 3bfae88..1559d07 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -700,8 +700,8 @@
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"應用程式可能無法在分割畫面中運作。"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"這個應用程式不支援分割畫面。"</string>
-    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"應用程式可能無法在第二個顯示器上運作。"</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"應用程式不支援在第二個顯示器上啟動。"</string>
+    <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"應用程式可能無法在次要顯示器上運作。"</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"應用程式無法在次要顯示器上啟動。"</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"開啟設定。"</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"開啟快速設定。"</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"關閉快速設定。"</string>
@@ -763,5 +763,5 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"保留"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"取代"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"在背景執行的應用程式"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕觸即可取得電池和數據用量的詳細資料"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕觸即可查看電池和數據用量詳情"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/arrays_tv.xml b/packages/SystemUI/res/values/arrays_tv.xml
index e52c5db..7541b0e 100644
--- a/packages/SystemUI/res/values/arrays_tv.xml
+++ b/packages/SystemUI/res/values/arrays_tv.xml
@@ -31,5 +31,6 @@
         <item>com.google.android.katniss.setting/.SpeechSettingsActivity</item>
         <item>com.google.android.katniss.setting/.SearchSettingsActivity</item>
         <item>com.google.android.gsf.notouch/.UsageDiagnosticsSettingActivity</item>
+        <item>com.google.android.tvlauncher/.notifications.NotificationsSidePanelActivity</item>
     </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 83a0b7b..8896e6f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -78,6 +78,9 @@
     <!-- The color of the material notification background when low priority -->
     <color name="notification_material_background_low_priority_color">#fff5f5f5</color>
 
+    <!-- The color of the dividing line between grouped notifications. -->
+    <color name="notification_divider_color">#FF616161</color>
+
     <!-- The background color of the notification shade -->
     <color name="notification_shade_background_color">#ffeeeeee</color>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index ffa5914..d3cbe4a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -369,4 +369,30 @@
          has rounded corners, then the contents will be clipped to those corners. -->
     <bool name="config_clipNotificationsToOutline">false</bool>
 
+    <!-- Whether or not notifications that can be expanded will always be in their expanded state.
+         This value only affects notifications that are not a group of notifications from the same
+         applications. If this value is false, then only the first notification will be expanded;
+         the other notifications need to be manually expanded by the user. -->
+    <bool name="config_alwaysExpandNonGroupedNotifications">false</bool>
+
+    <!-- Whether or not an expandable notification can be manually expanded or collapsed by the
+         user. Grouped notifications are still expandable even if this value is false. -->
+    <bool name="config_enableNonGroupedNotificationExpand">true</bool>
+
+    <!-- Whether or not there should be dividing lines between child notifications when the
+         group has been expanded. -->
+    <bool name="config_showDividersWhenGroupNotificationExpanded">false</bool>
+
+    <!-- Whether or not the dividing lines should be shown when the container is expanding and
+         collapsing. If this value is true, then the lines will only show when the container has
+         been completely expanded. -->
+    <bool name="config_hideDividersDuringExpand">false</bool>
+
+    <!-- Whether or not child notifications that are part of a group will have shadows. -->
+    <bool name="config_enableShadowOnChildNotifications">true</bool>
+
+    <!-- Whether or not a view containing child notifications will have a custom background when
+         it has been expanded to reveal its children. -->
+    <bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values/config_tv.xml b/packages/SystemUI/res/values/config_tv.xml
index 40e3b12..ffd58dc 100644
--- a/packages/SystemUI/res/values/config_tv.xml
+++ b/packages/SystemUI/res/values/config_tv.xml
@@ -17,17 +17,9 @@
 <resources>
     <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
          when the PIP menu is shown with settings. -->
-    <string translatable="false" name="pip_settings_bounds">"662 54 1142 324"</string>
+    <string translatable="false" name="pip_settings_bounds">"662 756 1142 1026"</string>
 
     <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
          when the PIP menu is shown in center. -->
     <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
-
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
-         when the PIP is shown in Recents without focus. -->
-    <string translatable="false" name="pip_recents_bounds">"800 54 1120 234"</string>
-
-    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
-         when the PIP is shown in Recents with focus. -->
-    <string translatable="false" name="pip_recents_focused_bounds">"775 54 1145 262"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 9273f01..ffd3096 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -211,8 +211,6 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
-    <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
-
     <!-- Gravity for the notification panel -->
     <integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
 
@@ -332,6 +330,19 @@
     <!-- The corner radius of the shadow behind the notification. -->
     <dimen name="notification_shadow_radius">0dp</dimen>
 
+    <!-- The alpha of the dividing line between child notifications of a notification group. -->
+    <item name="notification_divider_alpha" format="float" type="dimen">0.5</item>
+
+    <!-- The height of the divider between the individual notifications in a notification
+         group. -->
+    <dimen name="notification_children_container_divider_height">@dimen/notification_divider_height</dimen>
+
+    <!-- The height of the header for a container containing child notifications. -->
+    <dimen name="notification_children_container_header_height">53dp</dimen>
+
+    <!-- The top margin for the notification children container in its non-expanded form. -->
+    <dimen name="notification_children_container_margin_top">@*android:dimen/notification_content_margin_top</dimen>
+
     <!-- The height of a notification header -->
     <dimen name="notification_header_height">53dp</dimen>
 
@@ -783,4 +794,19 @@
 
     <dimen name="signal_icon_size">17dp</dimen>
 
+    <dimen name="hwui_edge_margin">16dp</dimen>
+
+    <dimen name="volume_dialog_panel_width">315dp</dimen>
+    <dimen name="global_actions_panel_width">125dp</dimen>
+
+    <dimen name="global_actions_top_padding">100dp</dimen>
+
+    <dimen name="corner_size">16dp</dimen>
+    <dimen name="top_padding">0dp</dimen>
+    <dimen name="bottom_padding">48dp</dimen>
+    <dimen name="edge_margin">16dp</dimen>
+
+    <dimen name="rounded_corner_radius">0dp</dimen>
+    <dimen name="rounded_corner_content_padding">0dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index fc0c82c..3c6ad23 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -45,6 +45,7 @@
     <item type="id" name="shadow_alpha_animator_start_value_tag"/>
     <item type="id" name="doze_saved_filter_tag"/>
     <item type="id" name="qs_icon_tag"/>
+    <item type="id" name="qs_slash_tag"/>
     <item type="id" name="scrim"/>
     <item type="id" name="scrim_target"/>
     <item type="id" name="scrim_alpha_start"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bd539ea..7eb1e22 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1442,7 +1442,7 @@
     <string name="notification_header_default_channel">Notifications</string>
 
     <!-- Notification Inline Controls: Shown when a channel's notifications are currently blocked -->
-    <string name="notification_channel_disabled">You won\'t get these notifications anymore.</string>
+    <string name="notification_channel_disabled">You won\'t get these notifications anymore</string>
 
     <!-- Notification: Control panel: Label that shows how many channels are included in this bundle
         of notifications.  Replaces the channel name and only appears when there is more than one channel. -->
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index e578068..a9bdb71 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -17,6 +17,14 @@
  */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Picture-in-Picture (PIP) notification -->
+    <!-- Title for the notification channel for TV PIP controls. [CHAR LIMIT=NONE] -->
+    <string name="notification_channel_tv_pip">Picture-in-Picture</string>
+    <!-- Title of the picture-in-picture (PIP) notification title
+         when the media doesn't have title [CHAR LIMIT=NONE] -->
+    <string name="pip_notification_unknown_title">(No title program)</string>
+
     <!-- Picture-in-Picture (PIP) menu -->
     <eat-comment />
     <!-- Button to close picture-in-picture (PIP) in PIP menu [CHAR LIMIT=30] -->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1ce34d4..47290ec 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -415,6 +415,10 @@
     private void onFingerprintAuthenticated(int userId) {
         Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
         mUserFingerprintAuthenticated.put(userId, true);
+        // Update/refresh trust state only if user can skip bouncer
+        if (getUserCanSkipBouncer(userId)) {
+            mTrustManager.unlockedByFingerprintForUser(userId);
+        }
         // Don't send cancel if authentication succeeds
         mFingerprintCancelSignal = null;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1649,6 +1653,7 @@
 
     public void clearFingerprintRecognized() {
         mUserFingerprintAuthenticated.clear();
+        mTrustManager.clearAllFingerprints();
     }
 
     public boolean isSimPinVoiceSecure() {
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index cfac2b7..79db544 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -77,6 +77,8 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerServiceImpl;
 import com.android.systemui.util.leak.GarbageMonitor;
@@ -84,6 +86,8 @@
 import com.android.systemui.util.leak.LeakReporter;
 import com.android.systemui.volume.VolumeDialogControllerImpl;
 
+import com.google.android.colorextraction.ColorExtractor;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.HashMap;
@@ -264,6 +268,10 @@
         mProviders.put(AccessibilityManagerWrapper.class,
                 () -> new AccessibilityManagerWrapper(mContext));
 
+        mProviders.put(ColorExtractor.class, () -> new ColorExtractor(mContext));
+
+        mProviders.put(TunablePaddingService.class, () -> new TunablePaddingService());
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
new file mode 100644
index 0000000..6417e29
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.Log;
+
+public class HardwareBgDrawable extends LayerDrawable {
+
+    private final Paint mPaint = new Paint();
+    private final Drawable[] mLayers;
+    private final boolean mRoundTop;
+    private int mPoint;
+    private boolean mRotatedBackground;
+
+    public HardwareBgDrawable(boolean roundTop, boolean roundEnd, Context context) {
+        this(roundTop, getLayers(context, roundTop, roundEnd));
+    }
+
+    public HardwareBgDrawable(boolean roundTop, Drawable[] layers) {
+        super(layers);
+        if (layers.length != 2) {
+            throw new IllegalArgumentException("Need 2 layers");
+        }
+        mRoundTop = roundTop;
+        mLayers = layers;
+        mLayers[1].setTint(0xffeeeeee);
+    }
+
+    private static Drawable[] getLayers(Context context, boolean roundTop, boolean roundEnd) {
+        int drawable = roundEnd ? R.drawable.rounded_bg_full : R.drawable.rounded_bg;
+        if (roundTop) {
+            return new Drawable[]{
+                    context.getDrawable(drawable).mutate(),
+                    context.getDrawable(drawable).mutate(),
+            };
+        }
+        return new Drawable[]{
+                context.getDrawable(drawable).mutate(),
+                context.getDrawable(roundEnd ? R.drawable.rounded_full_bg_bottom
+                        : R.drawable.rounded_bg_bottom).mutate(),
+        };
+    }
+
+    public void setCutPoint(int point) {
+        mPoint = point;
+        invalidateSelf();
+    }
+
+    public int getCutPoint() {
+        return mPoint;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mPoint >= 0 && !mRotatedBackground) {
+            Rect bounds = getBounds();
+            int top = bounds.top + mPoint;
+            if (top > bounds.bottom) top = bounds.bottom;
+            if (mRoundTop) {
+                mLayers[0].setBounds(bounds.left, bounds.top, bounds.right, top);
+            } else {
+                mLayers[1].setBounds(bounds.left, top, bounds.right, bounds.bottom);
+            }
+            if (mRoundTop) {
+                mLayers[1].draw(canvas);
+                mLayers[0].draw(canvas);
+            } else {
+                mLayers[0].draw(canvas);
+                mLayers[1].draw(canvas);
+            }
+        } else {
+            mLayers[0].draw(canvas);
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.OPAQUE;
+    }
+
+    public void setRotatedBackground(boolean rotatedBackground) {
+        mRotatedBackground = rotatedBackground;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
new file mode 100644
index 0000000..bb0f2f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class HardwareUiLayout extends FrameLayout implements Tunable {
+
+    private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
+    private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
+    private final int[] mTmp2 = new int[2];
+    private View mChild;
+    private int mOldHeight;
+    private boolean mAnimating;
+    private AnimatorSet mAnimation;
+    private View mDivision;
+    private boolean mHasOutsideTouch;
+    private HardwareBgDrawable mBackground;
+    private Animator mAnimator;
+    private boolean mCollapse;
+    private int mEndPoint;
+    private boolean mEdgeBleed;
+    private boolean mRoundedDivider;
+    private boolean mLandscape;
+    private boolean mRotatedBackground;
+
+    public HardwareUiLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        updateSettings();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateSettings();
+        Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
+        getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        updateSettings();
+    }
+
+    private void updateSettings() {
+        mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
+                EDGE_BLEED, 0) != 0;
+        mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
+                ROUNDED_DIVIDER, 1) != 0;
+        updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+        mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
+        if (mChild != null) {
+            mChild.setBackground(mBackground);
+            requestLayout();
+        }
+    }
+
+    private void updateEdgeMargin(int edge) {
+        if (mChild != null) {
+            MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
+            if (mLandscape) {
+                params.topMargin = edge;
+            } else {
+                params.rightMargin = edge;
+            }
+            mChild.setLayoutParams(params);
+        }
+    }
+
+    private int getEdgePadding() {
+        return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mChild == null) {
+            if (getChildCount() != 0) {
+                mChild = getChildAt(0);
+                mChild.setBackground(mBackground);
+                updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+                mOldHeight = mChild.getMeasuredHeight();
+                mChild.addOnLayoutChangeListener(
+                        (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                                updatePosition());
+            } else {
+                return;
+            }
+        }
+        int newHeight = mChild.getMeasuredHeight();
+        if (newHeight != mOldHeight) {
+            animateChild(mOldHeight, newHeight);
+        }
+        post(() -> updatePosition());
+        boolean landscape = getMeasuredWidth() > getMeasuredHeight();
+        if (landscape != mLandscape) {
+            mLandscape = landscape;
+            if (mLandscape) {
+                toLandscape();
+                if (mChild instanceof LinearLayout) {
+                    mRotatedBackground = true;
+                    mBackground.setRotatedBackground(true);
+                    ((LinearLayout) mChild).setOrientation(LinearLayout.HORIZONTAL);
+                    swapDimens(mChild);
+                }
+            } else {
+                fromLandscape();
+                if (mChild instanceof LinearLayout) {
+                    mRotatedBackground = false;
+                    mBackground.setRotatedBackground(false);
+                    ((LinearLayout) mChild).setOrientation(LinearLayout.VERTICAL);
+                    swapDimens(mChild);
+                }
+            }
+        }
+    }
+
+    private void fromLandscape() {
+        rotateRight(this);
+        rotateRight(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityRight(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private void swapDimens(View v) {
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        int h = params.width;
+        params.width = params.height;
+        params.height = h;
+        v.setLayoutParams(params);
+    }
+
+    private int rotateGravityRight(int gravity) {
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.BOTTOM;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.TOP;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.LEFT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.RIGHT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void toLandscape() {
+        rotateLeft(this);
+        rotateLeft(mChild);
+        swapDimens(this);
+
+        LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+        p.gravity = rotateGravityLeft(p.gravity);
+        mChild.setLayoutParams(p);
+    }
+
+    private int rotateGravityLeft(int gravity) {
+        if (gravity == -1) {
+            gravity = Gravity.TOP | Gravity.START;
+        }
+        int retGravity = 0;
+        int layoutDirection = getLayoutDirection();
+        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.CENTER_HORIZONTAL:
+                retGravity |= Gravity.CENTER_VERTICAL;
+                break;
+            case Gravity.RIGHT:
+                retGravity |= Gravity.TOP;
+                break;
+            case Gravity.LEFT:
+            default:
+                retGravity |= Gravity.BOTTOM;
+                break;
+        }
+
+        switch (verticalGravity) {
+            case Gravity.CENTER_VERTICAL:
+                retGravity |= Gravity.CENTER_HORIZONTAL;
+                break;
+            case Gravity.BOTTOM:
+                retGravity |= Gravity.RIGHT;
+                break;
+            case Gravity.TOP:
+            default:
+                retGravity |= Gravity.LEFT;
+                break;
+        }
+        return retGravity;
+    }
+
+    private void rotateLeft(View v) {
+        v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
+                v.getPaddingLeft());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
+                params.leftMargin);
+        v.setLayoutParams(params);
+    }
+
+    private void rotateRight(View v) {
+        v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
+                v.getPaddingRight());
+        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+        params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
+                params.rightMargin);
+        v.setLayoutParams(params);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        post(() -> updatePosition());
+    }
+
+    private void animateChild(int oldHeight, int newHeight) {
+        if (true) return;
+        if (mAnimating) {
+            mAnimation.cancel();
+        }
+        mAnimating = true;
+        mAnimation = new AnimatorSet();
+        mAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnimating = false;
+            }
+        });
+        int fromTop = mChild.getTop();
+        int fromBottom = mChild.getBottom();
+        int toTop = fromTop - ((newHeight - oldHeight) / 2);
+        int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
+        ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
+        top.addUpdateListener(animation -> mBackground.invalidateSelf());
+        mAnimation.playTogether(top,
+                ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
+    }
+
+    public void setDivisionView(View v) {
+        mDivision = v;
+        if (mDivision != null) {
+            mDivision.addOnLayoutChangeListener(
+                    (v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                            updatePosition());
+        }
+        updatePosition();
+    }
+
+    private void updatePosition() {
+        if (mChild == null) return;
+        if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
+            int index = mRotatedBackground ? 0 : 1;
+            mDivision.getLocationOnScreen(mTmp2);
+            float trans = mRotatedBackground ? mDivision.getTranslationX()
+                    : mDivision.getTranslationY();
+            int viewTop = (int) (mTmp2[index] + trans);
+            mChild.getLocationOnScreen(mTmp2);
+            viewTop -= mTmp2[index];
+            setCutPoint(viewTop);
+        } else {
+            setCutPoint(mChild.getMeasuredHeight());
+        }
+    }
+
+    private void setCutPoint(int point) {
+        int curPoint = mBackground.getCutPoint();
+        if (curPoint == point) return;
+        if (getAlpha() == 0 || curPoint == 0) {
+            mBackground.setCutPoint(point);
+            return;
+        }
+        if (mAnimator != null) {
+            if (mEndPoint == point) {
+                return;
+            }
+            mAnimator.cancel();
+        }
+        mEndPoint = point;
+        mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
+        if (mCollapse) {
+            mAnimator.setStartDelay(300);
+            mCollapse = false;
+        }
+        mAnimator.start();
+    }
+
+    @Override
+    public ViewOutlineProvider getOutlineProvider() {
+        return super.getOutlineProvider();
+    }
+
+    public void setOutsideTouchListener(OnClickListener onClickListener) {
+        mHasOutsideTouch = true;
+        requestLayout();
+        setOnClickListener(onClickListener);
+        setClickable(true);
+        setFocusable(true);
+    }
+
+    public void setCollapse() {
+        mCollapse = true;
+    }
+
+    public static HardwareUiLayout get(View v) {
+        if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
+        if (v.getParent() instanceof View) {
+            return get((View) v.getParent());
+        }
+        return null;
+    }
+
+    private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
+        if (mHasOutsideTouch || (mChild == null)) {
+            inoutInfo.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+            return;
+        }
+        inoutInfo.setTouchableInsets(
+                ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
+        inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
+                0, getBottom() - mChild.getBottom());
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
new file mode 100644
index 0000000..c4740af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+
+import android.app.Fragment;
+import android.graphics.PixelFormat;
+import android.support.annotation.VisibleForTesting;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
+
+import com.android.systemui.R.id;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class RoundedCorners extends SystemUI implements Tunable {
+    public static final String SIZE = "sysui_rounded_size";
+    public static final String PADDING = "sysui_rounded_content_padding";
+
+    private int mRoundedDefault;
+    private View mOverlay;
+    private View mBottomOverlay;
+    private float mDensity;
+    private TunablePadding mQsPadding;
+    private TunablePadding mStatusBarPadding;
+    private TunablePadding mNavBarPadding;
+
+    @Override
+    public void start() {
+        mRoundedDefault = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius);
+        if (mRoundedDefault == 0) {
+            // No rounded corners on this device.
+            return;
+        }
+
+        mOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        mOverlay.findViewById(R.id.right).setRotation(90);
+
+        mContext.getSystemService(WindowManager.class)
+                .addView(mOverlay, getWindowLayoutParams());
+        mBottomOverlay = LayoutInflater.from(mContext)
+                .inflate(R.layout.rounded_corners, null);
+        mBottomOverlay.findViewById(R.id.right).setRotation(180);
+        mBottomOverlay.findViewById(R.id.left).setRotation(270);
+        WindowManager.LayoutParams layoutParams = getWindowLayoutParams();
+        layoutParams.gravity = Gravity.BOTTOM;
+        mContext.getSystemService(WindowManager.class)
+                .addView(mBottomOverlay, layoutParams);
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+
+        Dependency.get(TunerService.class).addTunable(this, SIZE);
+
+        // Add some padding to all the content near the edge of the screen.
+        int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+        StatusBar sb = getComponent(StatusBar.class);
+        View statusBar = sb.getStatusBarWindow();
+
+        TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
+                padding, FLAG_END);
+
+        FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener(
+                NavigationBarFragment.TAG,
+                new TunablePaddingTagListener(padding, 0));
+
+        FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
+        fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
+                new TunablePaddingTagListener(padding, R.id.status_bar));
+        fragmentHostManager.addTagListener(QS.TAG,
+                new TunablePaddingTagListener(padding, R.id.header));
+    }
+
+    private WindowManager.LayoutParams getWindowLayoutParams() {
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                LayoutParams.WRAP_CONTENT,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                0
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_SLIPPERY
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                ,
+                PixelFormat.TRANSLUCENT);
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        lp.setTitle("RoundedOverlay");
+        lp.gravity = Gravity.TOP;
+        return lp;
+    }
+
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (mOverlay == null) return;
+        if (SIZE.equals(key)) {
+            int size = mRoundedDefault;
+            try {
+                size = (int) (Integer.parseInt(newValue) * mDensity);
+            } catch (Exception e) {
+            }
+            setSize(mOverlay.findViewById(R.id.left), size);
+            setSize(mOverlay.findViewById(R.id.right), size);
+            setSize(mBottomOverlay.findViewById(R.id.left), size);
+            setSize(mBottomOverlay.findViewById(R.id.right), size);
+        }
+    }
+
+    private void setSize(View view, int pixelSize) {
+        LayoutParams params = view.getLayoutParams();
+        params.width = pixelSize;
+        params.height = pixelSize;
+        view.setLayoutParams(params);
+    }
+
+    @VisibleForTesting
+    static class TunablePaddingTagListener implements FragmentListener {
+
+        private final int mPadding;
+        private final int mId;
+        private TunablePadding mTunablePadding;
+
+        public TunablePaddingTagListener(int padding, int id) {
+            mPadding = padding;
+            mId = id;
+        }
+
+        @Override
+        public void onFragmentViewCreated(String tag, Fragment fragment) {
+            if (mTunablePadding != null) {
+                mTunablePadding.destroy();
+            }
+            View view = fragment.getView();
+            if (mId != 0) {
+                view = view.findViewById(mId);
+            }
+            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
+                    FLAG_START | FLAG_END);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 0eb469f..4a45997 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -87,6 +87,7 @@
             GarbageMonitor.Service.class,
             LatencyTester.class,
             GlobalActionsComponent.class,
+            RoundedCorners.class,
     };
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 206342e..4af21eb 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -15,15 +15,16 @@
 package com.android.systemui.globalactions;
 
 import com.android.internal.R;
-import com.android.internal.app.AlertController;
-import com.android.internal.app.AlertController.AlertParams;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.EmergencyAffordanceManager;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.HardwareUiLayout;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
+import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
+import com.android.systemui.volume.VolumeDialogMotion.LogDecelerateInterpolator;
 
 import android.app.ActivityManager;
 import android.app.Dialog;
@@ -34,11 +35,13 @@
 import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
@@ -56,8 +59,6 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -65,10 +66,11 @@
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
-import android.widget.ListView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import java.util.ArrayList;
@@ -79,7 +81,7 @@
  * may show depending on whether the keyguard is showing, and whether the device
  * is provisioned.
  */
-class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
+class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -162,6 +164,7 @@
 
     /**
      * Show the global actions dialog (creating if necessary)
+     *
      * @param keyguardShowing True if keyguard is showing
      */
     public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
@@ -205,12 +208,14 @@
             mDialog.getWindow().setAttributes(attrs);
             mDialog.show();
             mWindowManagerFuncs.onGlobalActionsShown();
-            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
+            mDialog.getWindow().getDecorView().setSystemUiVisibility(
+                    View.STATUS_BAR_DISABLE_EXPAND);
         }
     }
 
     /**
      * Create the global actions dialog.
+     *
      * @return A new dialog.
      */
     private ActionsDialog createDialog() {
@@ -314,28 +319,19 @@
 
         mAdapter = new MyAdapter();
 
-        AlertParams params = new AlertParams(mContext);
-        params.mAdapter = mAdapter;
-        params.mOnClickListener = this;
-        params.mForceInverseBackground = true;
-
-        ActionsDialog dialog = new ActionsDialog(mContext, params);
+        OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
+            @Override
+            public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
+                    long id) {
+                final Action action = mAdapter.getItem(position);
+                if (action instanceof LongPressAction) {
+                    return ((LongPressAction) action).onLongPress();
+                }
+                return false;
+            }
+        };
+        ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
         dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
-
-        dialog.getListView().setItemsCanFocus(true);
-        dialog.getListView().setLongClickable(true);
-        dialog.getListView().setOnItemLongClickListener(
-                new AdapterView.OnItemLongClickListener() {
-                    @Override
-                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
-                            long id) {
-                        final Action action = mAdapter.getItem(position);
-                        if (action instanceof LongPressAction) {
-                            return ((LongPressAction) action).onLongPress();
-                        }
-                        return false;
-                    }
-        });
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
 
         dialog.setOnDismissListener(this);
@@ -346,7 +342,7 @@
     private final class PowerAction extends SinglePressAction implements LongPressAction {
         private PowerAction() {
             super(R.drawable.ic_lock_power_off,
-                R.string.global_action_power_off);
+                    R.string.global_action_power_off);
         }
 
         @Override
@@ -614,7 +610,7 @@
                     SinglePressAction switchToUser = new SinglePressAction(
                             R.drawable.ic_menu_cc, icon,
                             (user.name != null ? user.name : "Primary")
-                            + (isCurrentUser ? " \u2714" : "")) {
+                                    + (isCurrentUser ? " \u2714" : "")) {
                         public void onPress() {
                             try {
                                 ActivityManager.getService().switchUser(user.id);
@@ -652,7 +648,7 @@
         if (!mHasVibrator) {
             final boolean silentModeOn =
                     mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
-            ((ToggleAction)mSilentModeAction).updateState(
+            ((ToggleAction) mSilentModeAction).updateState(
                     silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
         }
     }
@@ -681,7 +677,8 @@
     /**
      * The adapter used for the list within the global actions dialog, taking
      * into account whether the keyguard is showing via
-     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether the device is provisioned
+     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
+     * the device is provisioned
      * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
      */
     private class MyAdapter extends BaseAdapter {
@@ -744,7 +741,11 @@
 
         public View getView(int position, View convertView, ViewGroup parent) {
             Action action = getItem(position);
-            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+            if (position == 2) {
+                HardwareUiLayout.get(parent).setDivisionView(view);
+            }
+            return view;
         }
     }
 
@@ -760,7 +761,7 @@
     private interface Action {
         /**
          * @return Text that will be announced when dialog is created.  null
-         *     for none.
+         * for none.
          */
         CharSequence getLabelForAccessibility(Context context);
 
@@ -770,13 +771,13 @@
 
         /**
          * @return whether this action should appear in the dialog when the keygaurd
-         *    is showing.
+         * is showing.
          */
         boolean showDuringKeyguard();
 
         /**
          * @return whether this action should appear in the dialog before the
-         *   device is provisioned.
+         * device is provisioned.
          */
         boolean showBeforeProvisioning();
 
@@ -834,7 +835,8 @@
 
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
-            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
+            View v = inflater.inflate(com.android.systemui.R.layout.global_actions_item, parent,
+                    false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -895,10 +897,10 @@
         protected int mDisabledStatusMessageResId;
 
         /**
-         * @param enabledIconResId The icon for when this action is on.
-         * @param disabledIconResid The icon for when this action is off.
-         * @param message The general information message, e.g 'Silent Mode'
-         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
+         * @param enabledIconResId           The icon for when this action is on.
+         * @param disabledIconResid          The icon for when this action is off.
+         * @param message                    The general information message, e.g 'Silent Mode'
+         * @param enabledStatusMessageResId  The on status message, e.g 'sound disabled'
          * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
          */
         public ToggleAction(int enabledIconResId,
@@ -931,7 +933,7 @@
             willCreate();
 
             View v = inflater.inflate(R
-                            .layout.global_actions_item, parent, false);
+                    .layout.global_actions_item, parent, false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -979,6 +981,7 @@
          * Implementations may override this if their state can be in on of the intermediate
          * states until some notification is received (e.g airplane mode is 'turning off' until
          * we know the wireless connections are back online
+         *
          * @param buttonOn Whether the button was turned on or off
          */
         protected void changeStateFromPress(boolean buttonOn) {
@@ -1020,7 +1023,7 @@
 
     private static class SilentModeTriStateAction implements Action, View.OnClickListener {
 
-        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+        private final int[] ITEM_IDS = {R.id.option1, R.id.option2, R.id.option3};
 
         private final AudioManager mAudioManager;
         private final Handler mHandler;
@@ -1145,19 +1148,19 @@
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MESSAGE_DISMISS:
-                if (mDialog != null) {
-                    mDialog.dismiss();
-                    mDialog = null;
-                }
-                break;
-            case MESSAGE_REFRESH:
-                refreshSilentMode();
-                mAdapter.notifyDataSetChanged();
-                break;
-            case MESSAGE_SHOW:
-                handleShow();
-                break;
+                case MESSAGE_DISMISS:
+                    if (mDialog != null) {
+                        mDialog.dismiss();
+                        mDialog = null;
+                    }
+                    break;
+                case MESSAGE_REFRESH:
+                    refreshSilentMode();
+                    mAdapter.notifyDataSetChanged();
+                    break;
+                case MESSAGE_SHOW:
+                    handleShow();
+                    break;
             }
         }
     };
@@ -1192,39 +1195,81 @@
     }
 
     private static final class ActionsDialog extends Dialog implements DialogInterface {
-        private final Context mContext;
-        private final AlertController mAlert;
-        private final MyAdapter mAdapter;
 
-        public ActionsDialog(Context context, AlertParams params) {
-            super(context, getDialogTheme(context));
+        private final Context mContext;
+        private final MyAdapter mAdapter;
+        private final LinearLayout mListView;
+        private final HardwareUiLayout mHardwareLayout;
+        private final OnClickListener mClickListener;
+        private final OnItemLongClickListener mLongClickListener;
+
+        public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
+                OnItemLongClickListener longClickListener) {
+            super(context, android.R.style.Theme_DeviceDefault_Light_NoActionBar_Fullscreen);
             mContext = getContext();
-            mAlert = AlertController.create(mContext, this, getWindow());
-            mAdapter = (MyAdapter) params.mAdapter;
-            params.apply(mAlert);
+            mAdapter = adapter;
+            mClickListener = clickListener;
+            mLongClickListener = longClickListener;
+            setContentView(com.android.systemui.R.layout.global_actions_wrapped);
+            getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+            mListView = findViewById(android.R.id.list);
+            mHardwareLayout = HardwareUiLayout.get(mListView);
+            mHardwareLayout.setOutsideTouchListener(view -> dismiss());
         }
 
-        private static int getDialogTheme(Context context) {
-            TypedValue outValue = new TypedValue();
-            context.getTheme().resolveAttribute(R.attr.alertDialogTheme,
-                    outValue, true);
-            return outValue.resourceId;
+        private void updateList() {
+            mListView.removeAllViews();
+            for (int i = 0; i < mAdapter.getCount(); i++) {
+                View v = mAdapter.getView(i, null, mListView);
+                final int pos = i;
+                v.setOnClickListener(view -> mClickListener.onClick(this, pos));
+                v.setOnLongClickListener(view ->
+                        mLongClickListener.onItemLongClick(null, v, pos, 0));
+                mListView.addView(v);
+            }
         }
 
         @Override
         protected void onStart() {
             super.setCanceledOnTouchOutside(true);
             super.onStart();
-        }
-
-        public ListView getListView() {
-            return mAlert.getListView();
+            updateList();
         }
 
         @Override
-        protected void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mAlert.installContent();
+        protected void onStop() {
+            super.onStop();
+        }
+
+        @Override
+        public void show() {
+            super.show();
+            mHardwareLayout.setTranslationX(getAnimTranslation());
+            mHardwareLayout.setAlpha(0);
+            mHardwareLayout.animate()
+                    .alpha(1)
+                    .translationX(0)
+                    .setDuration(300)
+                    .setInterpolator(new LogDecelerateInterpolator())
+                    .start();
+        }
+
+        @Override
+        public void dismiss() {
+            mHardwareLayout.setTranslationX(0);
+            mHardwareLayout.setAlpha(1);
+            mHardwareLayout.animate()
+                    .alpha(0)
+                    .translationX(getAnimTranslation())
+                    .setDuration(300)
+                    .withEndAction(() -> super.dismiss())
+                    .setInterpolator(new LogAccelerateInterpolator())
+                    .start();
+        }
+
+        private float getAnimTranslation() {
+            return getContext().getResources().getDimension(
+                    com.android.systemui.R.dimen.global_actions_panel_width) / 2;
         }
 
         @Override
@@ -1240,21 +1285,5 @@
             }
             return super.dispatchPopulateAccessibilityEvent(event);
         }
-
-        @Override
-        public boolean onKeyDown(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyDown(keyCode, event)) {
-                return true;
-            }
-            return super.onKeyDown(keyCode, event);
-        }
-
-        @Override
-        public boolean onKeyUp(int keyCode, KeyEvent event) {
-            if (mAlert.onKeyUp(keyCode, event)) {
-                return true;
-            }
-            return super.onKeyUp(keyCode, event);
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 07bd242..88e8b39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1585,7 +1585,6 @@
             updateInputRestricted();
         }
 
-        mDismissCallbackRegistry.notifyDismissSucceeded();
         handleHide();
         Trace.endSection();
     }
@@ -1798,6 +1797,7 @@
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
+            mDismissCallbackRegistry.notifyDismissSucceeded();
             sendUserPresentBroadcast();
         }
         Trace.endSection();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 9735bfc..6667b71 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -61,7 +61,8 @@
  */
 public class PipManager implements BasePipManager {
     private static final String TAG = "PipManager";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
     private static final String SETTINGS_PACKAGE_AND_CLASS_DELIMITER = "/";
 
     private static PipManager sPipManager;
@@ -122,6 +123,7 @@
     private ComponentName mPipComponentName;
     private MediaController mPipMediaController;
     private String[] mLastPackagesResourceGranted;
+    private PipNotification mPipNotification;
 
     private final PinnedStackListener mPinnedStackListener = new PinnedStackListener();
 
@@ -246,6 +248,8 @@
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to register pinned stack listener", e);
         }
+
+        mPipNotification = new PipNotification(context);
     }
 
     private void loadConfigurationsAndApply() {
@@ -267,6 +271,7 @@
      */
     public void onConfigurationChanged() {
         loadConfigurationsAndApply();
+        mPipNotification.onConfigurationChanged(mContext);
     }
 
     /**
@@ -345,7 +350,7 @@
      * @param state In Pip state also used to determine the new size for the Pip.
      */
     void resizePinnedStack(int state) {
-        if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state);
+        if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state, new Exception());
         boolean wasStateNoPip = (mState == STATE_NO_PIP);
         mResumeResizePinnedStackRunnable = state;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
@@ -511,8 +516,8 @@
 
     /**
      * Returns the PIPed activity's playback state.
-     * This returns one of {@link PLAYBACK_STATE_PLAYING}, {@link PLAYBACK_STATE_PAUSED},
-     * or {@link PLAYBACK_STATE_UNAVAILABLE}.
+     * This returns one of {@link #PLAYBACK_STATE_PLAYING}, {@link #PLAYBACK_STATE_PAUSED},
+     * or {@link #PLAYBACK_STATE_UNAVAILABLE}.
      */
     int getPlaybackState() {
         if (mPipMediaController == null || mPipMediaController.getPlaybackState() == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
new file mode 100644
index 0000000..727eb5a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.pip.tv;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.media.MediaMetadata;
+import android.media.session.MediaController;
+import android.media.session.PlaybackState;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.util.NotificationChannels;
+import com.android.systemui.R;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+
+/**
+ * A notification that informs users that PIP is running and also provides PIP controls.
+ * <p>Once it's created, it will manage the PIP notification UI by itself except for handling
+ * configuration changes.
+ */
+public class PipNotification {
+    private static final String TAG = "PipNotification";
+    private static final boolean DEBUG = PipManager.DEBUG;
+
+    private static final String ACTION_MENU = "PipNotification.menu";
+    private static final String ACTION_CLOSE = "PipNotification.close";
+
+    private final PipManager mPipManager = PipManager.getInstance();
+
+    private final NotificationManager mNotificationManager;
+    private final Notification.Builder mNotificationBuilder;
+
+    private MediaController mMediaController;
+    private String mDefaultTitle;
+    private Icon mDefaultIcon;
+
+    private boolean mNotified;
+    private String mTitle;
+    private Bitmap mArt;
+
+    private PipManager.Listener mPipListener = new PipManager.Listener() {
+        @Override
+        public void onPipEntered() {
+            updateMediaControllerMetadata();
+            notifyPipNotification();
+        }
+
+        @Override
+        public void onPipActivityClosed() {
+            dismissPipNotification();
+        }
+
+        @Override
+        public void onShowPipMenu() {
+            // no-op.
+        }
+
+        @Override
+        public void onMoveToFullscreen() {
+            dismissPipNotification();
+        }
+
+        @Override
+        public void onPipResizeAboutToStart() {
+            // no-op.
+        }
+    };
+
+    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            if (updateMediaControllerMetadata() && mNotified) {
+                // update notification
+                notifyPipNotification();
+            }
+        }
+    };
+
+    private final PipManager.MediaListener mPipMediaListener = new PipManager.MediaListener() {
+        @Override
+        public void onMediaControllerChanged() {
+            MediaController newController = mPipManager.getMediaController();
+            if (mMediaController == newController) {
+                return;
+            }
+            if (mMediaController != null) {
+                mMediaController.unregisterCallback(mMediaControllerCallback);
+            }
+            mMediaController = newController;
+            if (mMediaController != null) {
+                mMediaController.registerCallback(mMediaControllerCallback);
+            }
+            if (updateMediaControllerMetadata() && mNotified) {
+                // update notification
+                notifyPipNotification();
+            }
+        }
+    };
+
+    private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Log.d(TAG, "Received " + intent.getAction() + " from the notification UI");
+            }
+            switch (intent.getAction()) {
+                case ACTION_MENU:
+                    mPipManager.showPictureInPictureMenu();
+                    break;
+                case ACTION_CLOSE:
+                    mPipManager.closePip();
+                    break;
+            }
+        }
+    };
+
+    public PipNotification(Context context) {
+        mNotificationManager = (NotificationManager) context.getSystemService(
+                Context.NOTIFICATION_SERVICE);
+
+        mNotificationBuilder = new Notification.Builder(context, NotificationChannels.TVPIP)
+                .setLocalOnly(true)
+                .setOngoing(false)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .extend(new Notification.TvExtender()
+                        .setContentIntent(createPendingIntent(context, ACTION_MENU))
+                        .setDeleteIntent(createPendingIntent(context, ACTION_CLOSE)));
+
+        mPipManager.addListener(mPipListener);
+        mPipManager.addMediaListener(mPipMediaListener);
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_MENU);
+        intentFilter.addAction(ACTION_CLOSE);
+        context.registerReceiver(mEventReceiver, intentFilter);
+
+        onConfigurationChanged(context);
+    }
+
+    /**
+     * Called by {@link PipManager} when the configuration is changed.
+     */
+    void onConfigurationChanged(Context context) {
+        Resources res = context.getResources();
+        mDefaultTitle = res.getString(R.string.pip_notification_unknown_title);
+        mDefaultIcon = Icon.createWithResource(context,
+                res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR
+                        ? R.drawable.pip_expand_ll : R.drawable.pip_expand_lr);
+        if (mNotified) {
+            // update notification
+            notifyPipNotification();
+        }
+    }
+
+    private void notifyPipNotification() {
+        mNotified = true;
+        mNotificationBuilder
+                .setShowWhen(true)
+                .setWhen(System.currentTimeMillis())
+                // TODO: Sending bitmap doesn't work in launcher side. Once launcher supports it,
+                // we can set icon.
+                //.setSmallIcon(mArt != null ? Icon.createWithBitmap(mArt) : mDefaultIcon)
+                .setSmallIcon(mDefaultIcon.getResId())
+                .setContentTitle(!TextUtils.isEmpty(mTitle) ? mTitle : mDefaultTitle);
+        mNotificationManager.notify(SystemMessage.NOTE_TV_PIP, mNotificationBuilder.build());
+    }
+
+    private void dismissPipNotification() {
+        mNotified = false;
+        mNotificationManager.cancel(SystemMessage.NOTE_TV_PIP);
+    }
+
+    private boolean updateMediaControllerMetadata() {
+        String title = null;
+        Bitmap art = null;
+        if (mPipManager.getMediaController() != null) {
+            MediaMetadata metadata = mPipManager.getMediaController().getMetadata();
+            if (metadata != null) {
+                title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE);
+                if (TextUtils.isEmpty(title)) {
+                    title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+                }
+                art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+                if (art == null) {
+                    art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
+                }
+            }
+        }
+        if (!TextUtils.equals(title, mTitle) || art != mArt) {
+            mTitle = title;
+            mArt = art;
+            return true;
+        }
+        return false;
+    }
+
+    private static PendingIntent createPendingIntent(Context context, String action) {
+        return PendingIntent.getBroadcast(context, 0,
+                new Intent(action), PendingIntent.FLAG_CANCEL_CURRENT);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 01f8169..d413030 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -27,6 +27,7 @@
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTile.SignalState;
 import com.android.systemui.qs.tileimpl.QSIconViewImpl;
+import com.android.systemui.qs.tileimpl.SlashImageView;
 
 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/
 public class SignalTileView extends QSIconViewImpl {
@@ -61,7 +62,7 @@
     @Override
     protected View createIcon() {
         mIconFrame = new FrameLayout(mContext);
-        mSignal = new ImageView(mContext);
+        mSignal = new SlashImageView(mContext);
         mIconFrame.addView(mSignal);
         return mIconFrame;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
new file mode 100644
index 0000000..6fe3c5a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.annotation.ColorInt;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.ColorStateList;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+public class SlashDrawable extends Drawable {
+
+    private final Path mPath = new Path();
+    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private static float[] OFFSET = {
+        1.3f / 24f,-1.3f / 24f
+    };
+    private static float[][] PATH = {
+            {21.9f / 24f, 21.9f / 24f},
+            {2.1f / 24f, 2.1f / 24f},
+            {0.8f / 24f, 3.4f / 24f},
+            {20.6f / 24f, 23.2f / 24f},
+    };
+    private Drawable mDrawable;
+    private float mRotation;
+    private boolean mSlashed;
+    private Mode mTintMode;
+    private ColorStateList mTintList;
+
+    public SlashDrawable(Drawable d) {
+        mDrawable = d;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mDrawable != null ? mDrawable.getIntrinsicHeight(): 0;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mDrawable != null ? mDrawable.getIntrinsicWidth(): 0;
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mDrawable.setBounds(bounds);
+    }
+
+    public void setDrawable(Drawable d) {
+        mDrawable = d;
+        mDrawable.setCallback(getCallback());
+        mDrawable.setBounds(getBounds());
+        if (mTintMode != null) mDrawable.setTintMode(mTintMode);
+        if (mTintList != null) mDrawable.setTintList(mTintList);
+        invalidateSelf();
+    }
+
+    public void setRotation(float rotation) {
+        if (mRotation == rotation) return;
+        mRotation = rotation;
+        invalidateSelf();
+    }
+
+    public void setSlashed(boolean slashed) {
+        Log.d("TestTest", "setSlashed " + slashed);
+        if (mSlashed == slashed) return;
+        // TODO: Animate.
+        mSlashed = slashed;
+        invalidateSelf();
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        canvas.save();
+        Log.d("TestTest", "draw " + mSlashed);
+        if (mSlashed) {
+            Matrix m = new Matrix();
+            int width = getBounds().width();
+            int height = getBounds().height();
+            mPath.reset();
+            mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height));
+            mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height));
+            mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height));
+            mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height));
+            mPath.close();
+            m = new Matrix();
+            m.setRotate(mRotation, width / 2, height / 2);
+            mPath.transform(m);
+            canvas.drawPath(mPath, mPaint);
+            m = new Matrix();
+            m.setRotate(-mRotation, width / 2, height / 2);
+            mPath.transform(m);
+
+            m = new Matrix();
+            m.setTranslate(scale(OFFSET[0], width), scale(OFFSET[1], height));
+            mPath.transform(m);
+            mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height));
+            mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height));
+            mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height));
+            mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height));
+            mPath.close();
+            m = new Matrix();
+            m.setRotate(mRotation, width / 2, height / 2);
+            mPath.transform(m);
+            canvas.clipOutPath(mPath);
+        }
+
+        mDrawable.draw(canvas);
+        canvas.restore();
+    }
+
+    private float scale(float frac, int width) {
+        return frac * width;
+    }
+
+    @Override
+    public void setTint(@ColorInt int tintColor) {
+        super.setTint(tintColor);
+        mDrawable.setTint(tintColor);
+        mPaint.setColor(tintColor);
+    }
+
+    @Override
+    public void setTintList(@Nullable ColorStateList tint) {
+        mTintList = tint;
+        super.setTintList(tint);
+        mDrawable.setTintList(tint);
+        mPaint.setColor(tint.getDefaultColor());
+        invalidateSelf();
+    }
+
+    @Override
+    public void setTintMode(@NonNull Mode tintMode) {
+        mTintMode = tintMode;
+        super.setTintMode(tintMode);
+        mDrawable.setTintMode(tintMode);
+    }
+
+    @Override
+    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
+        mDrawable.setAlpha(alpha);
+        mPaint.setAlpha(alpha);
+    }
+
+    @Override
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
+        mDrawable.setColorFilter(colorFilter);
+        mPaint.setColorFilter(colorFilter);
+    }
+
+    @Override
+    public int getOpacity() {
+        return 255;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index 661c921..b39fc11 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -21,7 +21,6 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
-import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.Animatable2.AnimationCallback;
 import android.graphics.drawable.Drawable;
@@ -85,7 +84,8 @@
     }
 
     protected void updateIcon(ImageView iv, State state) {
-        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))
+                || !Objects.equals(state.slash, iv.getTag(R.id.qs_slash_tag))) {
             boolean shouldAnimate = iv.isShown() && mAnimationEnabled
                     && iv.getDrawable() != null;
             Drawable d = state.icon != null
@@ -96,7 +96,11 @@
                 d.setAutoMirrored(false);
             }
             iv.setImageDrawable(d);
+            if (state.slash != null && iv instanceof SlashImageView) {
+                ((SlashImageView) iv).setState(state.slash);
+            }
             iv.setTag(R.id.qs_icon_tag, state.icon);
+            iv.setTag(R.id.qs_slash_tag, state.slash);
             iv.setPadding(0, padding, 0, padding);
             if (d instanceof Animatable2) {
                 Animatable2 a = (Animatable2) d;
@@ -166,7 +170,7 @@
     }
 
     protected View createIcon() {
-        final ImageView icon = new ImageView(mContext);
+        final ImageView icon = new SlashImageView(mContext);
         icon.setId(android.R.id.icon);
         icon.setScaleType(ScaleType.FIT_CENTER);
         return icon;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
new file mode 100644
index 0000000..603f66b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs.tileimpl;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+
+import com.android.systemui.plugins.qs.QSTile.SlashState;
+import com.android.systemui.qs.SlashDrawable;
+
+public class SlashImageView extends ImageView {
+
+    private SlashDrawable mSlash;
+
+    public SlashImageView(Context context) {
+        super(context);
+    }
+
+    private void ensureSlashDrawable() {
+        if (mSlash == null) {
+            mSlash = new SlashDrawable(getDrawable());
+            super.setImageDrawable(mSlash);
+        }
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        if (mSlash != null) {
+            mSlash.setDrawable(drawable);
+        } else {
+            super.setImageDrawable(drawable);
+        }
+    }
+
+    public void setState(SlashState slashState) {
+        ensureSlashDrawable();
+        mSlash.setRotation(slashState.rotation);
+        mSlash.setSlashed(slashState.isSlashed);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c5f798e..c0509c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -29,19 +29,15 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.GlobalSetting;
 import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation,
-                    R.drawable.ic_signal_airplane_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_airplane_disable_animation,
-                    R.drawable.ic_signal_airplane_enable);
+    private final Icon mIcon =
+            ResourceIcon.get(R.drawable.ic_signal_airplane_disable);
     private final GlobalSetting mSetting;
 
     private boolean mListening;
@@ -90,11 +86,11 @@
         final boolean airplaneMode = value != 0;
         state.value = airplaneMode;
         state.label = mContext.getString(R.string.airplane_mode);
-        if (airplaneMode) {
-            state.icon = mEnable;
-        } else {
-            state.icon = mDisable;
+        state.icon = mIcon;
+        if (state.slash == null) {
+            state.slash = new SlashState();
         }
+        state.slash.isSlashed = !airplaneMode;
         state.state = airplaneMode ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.contentDescription = state.label;
         state.expandedAccessibilityClassName = Switch.class.getName();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 9b20a7a..703be27 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -114,6 +114,10 @@
                 || mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
         state.dualTarget = true;
         state.value = enabled;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+        state.slash.isSlashed = !enabled;
         if (enabled) {
             state.label = null;
             if (connected) {
@@ -137,7 +141,7 @@
             }
             state.state = Tile.STATE_ACTIVE;
         } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);
+            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
             state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_bluetooth_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 5512993..6f28838 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -68,6 +68,7 @@
     private final Callback mCallback = new Callback();
     private final ActivityStarter mActivityStarter;
     private Dialog mDialog;
+    private boolean mRegistered;
 
     public CastTile(QSHost host) {
         super(host);
@@ -146,7 +147,7 @@
                 mDialog = dialog;
             }
             mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
-            mDialog.show();
+            mUiHandler.post(() -> mDialog.show());
             registerReceiver();
             mHost.collapsePanels();
         });
@@ -155,7 +156,13 @@
     private void registerReceiver() {
         mContext.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
                 new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
-        mDialog.setOnDismissListener(dialog -> mContext.unregisterReceiver(mReceiver));
+        mRegistered = true;
+        mDialog.setOnDismissListener(dialog -> {
+            if (mRegistered) {
+                mContext.unregisterReceiver(mReceiver);
+                mRegistered = false;
+            }
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 92ff17a1..a4aa262 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -127,13 +127,16 @@
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
-        state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
         state.state = cb.airplaneModeEnabled || !cb.enabled ? Tile.STATE_UNAVAILABLE
                 : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
+        state.slash.isSlashed = (state.state == Tile.STATE_INACTIVE);
         if (state.state == Tile.STATE_ACTIVE) {
             state.icon = ResourceIcon.get(R.drawable.ic_data_on);
         } else if (state.state == Tile.STATE_INACTIVE) {
-            state.icon = ResourceIcon.get(R.drawable.ic_data_off);
+            state.icon = ResourceIcon.get(R.drawable.ic_data_on);
         } else {
             state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 5b374b1..97a12c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -33,12 +34,7 @@
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_invert_colors_enable_animation,
-            R.drawable.ic_invert_colors_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation,
-            R.drawable.ic_invert_colors_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors_disable);
     private final SecureSetting mSetting;
 
     private boolean mListening;
@@ -96,10 +92,14 @@
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.value = enabled;
+        state.slash.isSlashed = !state.value;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
-        state.icon = enabled ? mEnable : mDisable;
+        state.icon = mIcon;
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index ecbc4f7..8c6363a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -27,7 +27,6 @@
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.net.Uri;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Global;
@@ -72,12 +71,7 @@
     private static final QSTile.Icon TOTAL_SILENCE =
             ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
 
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_dnd_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
-    private final AnimationIcon mDisableTotalSilence =
-            new AnimationIcon(R.drawable.ic_dnd_total_silence_disable_animation,
-                    R.drawable.ic_qs_dnd_off);
+    private final Icon mDisable = ResourceIcon.get(R.drawable.ic_qs_dnd_off);
 
     private final ZenModeController mController;
     private final DndDetailAdapter mDetailAdapter;
@@ -167,9 +161,11 @@
         final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
         final boolean newValue = zen != ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
+        if (state.slash == null) state.slash = new SlashState();
         state.dualTarget = true;
         state.value = newValue;
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.slash.isSlashed = !state.value;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
@@ -191,7 +187,7 @@
                         R.string.accessibility_quick_settings_dnd_alarms_on);
                 break;
             default:
-                state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
+                state.icon = mDisable;
                 state.label = mContext.getString(R.string.quick_settings_dnd_label);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_dnd);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 6d2aa90..b436e17 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -23,12 +23,11 @@
 import android.service.quicksettings.Tile;
 import android.widget.Switch;
 
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.FlashlightController;
 
@@ -36,12 +35,7 @@
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
 
-    private final AnimationIcon mEnable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation,
-            R.drawable.ic_signal_flashlight_disable);
-    private final AnimationIcon mDisable
-            = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation,
-            R.drawable.ic_signal_flashlight_enable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight_disable);
     private final FlashlightController mFlashlightController;
 
     public FlashlightTile(QSHost host) {
@@ -104,6 +98,9 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (!mFlashlightController.isAvailable()) {
             Drawable icon = mHost.getContext().getDrawable(R.drawable.ic_signal_flashlight_enable)
@@ -123,8 +120,8 @@
         } else {
             state.value = mFlashlightController.isEnabled();
         }
-        final AnimationIcon icon = state.value ? mEnable : mDisable;
-        state.icon = icon;
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 40f2c4b..1c7c578 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -39,14 +39,7 @@
     static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
              "com.android.settings", "com.android.settings.TetherSettings"));
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
-                    R.drawable.ic_hotspot_disable);
     private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
-                    R.drawable.ic_hotspot_enable);
-    private final Icon mDisableNoAnimation = ResourceIcon.get(R.drawable.ic_hotspot_enable);
     private final Icon mUnavailable = ResourceIcon.get(R.drawable.ic_hotspot_unavailable);
 
     private final HotspotController mController;
@@ -116,6 +109,9 @@
 
     @Override
     protected void handleUpdateState(AirplaneBooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
@@ -124,18 +120,12 @@
         } else {
             state.value = mController.isHotspotEnabled();
         }
-        state.icon = !state.value ? mDisable
-                : state.isTransient ? mEnabledStatic
-                : mEnable;
-        boolean wasAirplane = state.isAirplaneMode;
+        state.icon = mEnabledStatic;
         state.isAirplaneMode = mAirplaneMode.getValue() != 0;
         state.isTransient = mController.isHotspotTransient();
+        state.slash.isSlashed = !state.value && !state.isTransient;
         if (state.isTransient) {
             state.icon = ResourceIcon.get(R.drawable.ic_hotspot_transient_animation);
-        } else if (state.isAirplaneMode) {
-            state.icon = mUnavailable;
-        } else if (wasAirplane) {
-            state.icon = mDisableNoAnimation;
         }
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 6522e10..96f2f68 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -25,6 +25,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.R.drawable;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.plugins.qs.QSTile.BooleanState;
@@ -36,12 +37,7 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
-    private final AnimationIcon mEnable =
-            new AnimationIcon(R.drawable.ic_signal_location_enable_animation,
-                    R.drawable.ic_signal_location_disable);
-    private final AnimationIcon mDisable =
-            new AnimationIcon(R.drawable.ic_signal_location_disable_animation,
-                    R.drawable.ic_signal_location_enable);
+    private final Icon mIcon = ResourceIcon.get(drawable.ic_signal_location_disable);
 
     private final LocationController mController;
     private final KeyguardMonitor mKeyguard;
@@ -95,6 +91,9 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        if (state.slash == null) {
+            state.slash = new SlashState();
+        }
         final boolean locationEnabled =  mController.isLocationEnabled();
 
         // Work around for bug 15916487: don't show location tile on top of lock screen. After the
@@ -102,13 +101,13 @@
         // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
         state.value = locationEnabled;
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
+        state.icon = mIcon;
+        state.slash.isSlashed = !state.value;
         if (locationEnabled) {
-            state.icon = mEnable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_on);
         } else {
-            state.icon = mDisable;
             state.label = mContext.getString(R.string.quick_settings_location_label);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_location_off);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 1afce64..b346d40 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -150,6 +150,12 @@
             mDetailAdapter.setItemsVisible(cb.enabled);
             fireToggleStateChanged(cb.enabled);
         }
+        if (state.slash == null) {
+            state.slash = new SlashState();
+            state.slash.rotation = 8;
+        }
+        state.slash.isSlashed = false;
+        state.state = Tile.STATE_ACTIVE;
         state.dualTarget = true;
         state.value = cb.enabled;
         state.activityIn = cb.enabled && cb.activityIn;
@@ -160,6 +166,8 @@
             state.icon = ResourceIcon.get(R.drawable.ic_signal_wifi_transient_animation);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (!state.value) {
+            state.slash.isSlashed = true;
+            state.state = Tile.STATE_INACTIVE;
             state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
             state.label = r.getString(R.string.quick_settings_wifi_label);
         } else if (wifiConnected) {
@@ -184,7 +192,6 @@
         state.dualLabelContentDescription = r.getString(
                 R.string.accessibility_quick_settings_open_settings, getTileLabel());
         state.expandedAccessibilityClassName = Switch.class.getName();
-        state.state = Tile.STATE_ACTIVE;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 7bc591f..4e17bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -374,6 +374,8 @@
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true));
         MetricsLogger.visible(this, MetricsEvent.OVERVIEW_ACTIVITY);
 
+        // Make sure we have the right gradient and we're listening for update events
+        mRecentsView.onStart();
         // Notify of the next draw
         mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener);
 
@@ -534,6 +536,9 @@
         MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
         Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(false);
 
+        // We don't need to update the gradient when we're not visible
+        mRecentsView.onStop();
+
         if (!isChangingConfigurations()) {
             // Workaround for b/22542869, if the RecentsActivity is started again, but without going
             // through SystemUI, we need to reset the config launch flags to ensure that we do not
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 2401e67..6879436 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -45,6 +45,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -145,11 +146,7 @@
         mBackgroundScrim = new GradientDrawable(context);
         mBackgroundScrim.setCallback(this);
         mBackgroundScrim.setAlpha((int) (mScrimAlpha * 255));
-        mColorExtractor = new ColorExtractor(context);
-        mColorExtractor.setListener(this);
-        // We don't want to interpolate colors because we're defining the initial state.
-        // Gradient should be set/ready when you open "Recents".
-        mBackgroundScrim.setColors(mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM), false);
+        mColorExtractor = Dependency.get(ColorExtractor.class);
 
         LayoutInflater inflater = LayoutInflater.from(context);
         if (RecentsDebugFlags.Static.EnableStackActionButton) {
@@ -828,4 +825,15 @@
             mBackgroundScrim.setColors(colors);
         }
     }
+
+    public void onStart() {
+        mColorExtractor.addOnColorsChangedListener(this);
+        // We don't want to interpolate colors because we're defining the initial state.
+        // Gradient should be set/ready when you open "Recents".
+        mBackgroundScrim.setColors(mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM), false);
+    }
+
+    public void onStop() {
+        mColorExtractor.removeOnColorsChangedListener(this);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index e34987b..4b614ed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -362,11 +362,17 @@
      * Cancels any current transform animations.
      */
     public void cancelTransformAnimation() {
+        cancelDimAnimationIfExists();
         Utilities.cancelAnimationWithoutCallbacks(mTransformAnimation);
-        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
         Utilities.cancelAnimationWithoutCallbacks(mOutlineAnimator);
     }
 
+    private void cancelDimAnimationIfExists() {
+        if (mDimAnimator != null) {
+            mDimAnimator.cancel();
+        }
+    }
+
     /** Enables/disables handling touch on this task view. */
     public void setTouchEnabled(boolean enabled) {
         setOnClickListener(enabled ? this : null);
@@ -546,7 +552,7 @@
     @Override
     public void onStartLaunchTargetEnterAnimation(TaskViewTransform transform, int duration,
             boolean screenPinningEnabled, ReferenceCountedTrigger postAnimationTrigger) {
-        Utilities.cancelAnimationWithoutCallbacks(mDimAnimator);
+        cancelDimAnimationIfExists();
 
         // Dim the view after the app window transitions down into recents
         postAnimationTrigger.increment();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index da56e62..90c65580 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -767,7 +767,7 @@
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
             mIsInMinimizeInteraction = true;
-            if (minimized) {
+            if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())) {
                 mDividerPositionBeforeMinimized = getCurrentPosition();
             }
             mMinimizedSnapAlgorithm = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java b/packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java
new file mode 100644
index 0000000..d5ec4f67
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+/**
+ * An interface that allows aborting existing operations.
+ */
+public interface Abortable {
+    void abort();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index d7eab97..b91561e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -891,7 +891,7 @@
      * @return the calculated background color
      */
     private int calculateBgColor(boolean withTint, boolean withOverRide) {
-        if (mDark) {
+        if (withTint && mDark) {
             return getContext().getColor(R.color.notification_material_background_dark_color);
         }
         if (withOverRide && mOverrideTint != NO_COLOR) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 8887bea..ac8219c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -170,6 +170,18 @@
     private OnExpandClickListener mOnExpandClickListener;
     private boolean mGroupExpansionChanging;
 
+    /**
+     * Whether or not a notification that is not part of a group of notifications can be manually
+     * expanded by the user.
+     */
+    private boolean mEnableNonGroupedNotificationExpand;
+
+    /**
+     * Whether or not to update the background of the header of the notification when its expanded.
+     * If {@code true}, the header background will disappear when expanded.
+     */
+    private boolean mShowGroupBackgroundWhenExpanded;
+
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -182,7 +194,7 @@
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
                 onExpansionChanged(true /* userAction */, wasExpanded);
-            } else {
+            } else if (mEnableNonGroupedNotificationExpand) {
                 if (v.isAccessibilityFocused()) {
                     mPrivateLayout.setFocusOnVisibilityChange();
                 }
@@ -362,7 +374,8 @@
                 NotificationColorUtil.getInstance(mContext));
         int color = StatusBarIconView.NO_COLOR;
         if (colorize) {
-            color = mEntry.getContrastedColor(mContext, mIsLowPriority && !isExpanded());
+            color = mEntry.getContrastedColor(mContext, mIsLowPriority && !isExpanded(),
+                    getBackgroundColorWithoutTint());
         }
         expandedIcon.setStaticDrawableColor(color);
     }
@@ -875,7 +888,8 @@
 
     private void updateNotificationColor() {
         mNotificationColor = NotificationColorUtil.resolveContrastColor(mContext,
-                getStatusBarNotification().getNotification().color);
+                getStatusBarNotification().getNotification().color,
+                getBackgroundColorWithoutTint());
     }
 
     public HybridNotificationView getSingleLineView() {
@@ -1146,7 +1160,7 @@
     }
 
     public interface ExpansionLogger {
-        public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
+        void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
@@ -1169,11 +1183,16 @@
         mMaxHeadsUpHeight = getFontScaledHeight(R.dimen.notification_max_heads_up_height);
         mMaxHeadsUpHeightIncreased = getFontScaledHeight(
                 R.dimen.notification_max_heads_up_height_increased);
+
         Resources res = getResources();
         mIncreasedPaddingBetweenElements = res.getDimensionPixelSize(
                 R.dimen.notification_divider_height_increased);
         mIconTransformContentShiftNoIcon = res.getDimensionPixelSize(
                 R.dimen.notification_icon_transform_content_shift);
+        mEnableNonGroupedNotificationExpand =
+                res.getBoolean(R.bool.config_enableNonGroupedNotificationExpand);
+        mShowGroupBackgroundWhenExpanded =
+                res.getBoolean(R.bool.config_showGroupNotificationBgWhenExpanded);
     }
 
     /**
@@ -1389,7 +1408,7 @@
         if (mIsSummaryWithChildren && !mShowingPublic) {
             return !mChildrenExpanded;
         }
-        return mExpandable;
+        return mEnableNonGroupedNotificationExpand && mExpandable;
     }
 
     public void setExpandable(boolean expandable) {
@@ -1990,7 +2009,8 @@
     public void updateBackgroundForGroupState() {
         if (mIsSummaryWithChildren) {
             // Only when the group has finished expanding do we hide its background.
-            mShowNoBackground = isGroupExpanded() && !isGroupExpansionChanging() && !isUserLocked();
+            mShowNoBackground = !mShowGroupBackgroundWhenExpanded && isGroupExpanded()
+                    && !isGroupExpansionChanging() && !isUserLocked();
             mChildrenContainer.updateHeaderForExpansion(mShowNoBackground);
             List<ExpandableNotificationRow> children = mChildrenContainer.getNotificationChildren();
             for (int i = 0; i < children.size(); i++) {
@@ -1999,10 +2019,10 @@
         } else if (isChildInGroup()) {
             final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
             // Only show a background if the group is expanded OR if it is expanding / collapsing
-            // and has a custom background color
+            // and has a custom background color.
             final boolean showBackground = isGroupExpanded()
                     || ((mNotificationParent.isGroupExpansionChanging()
-                            || mNotificationParent.isUserLocked()) && childColor != 0);
+                    || mNotificationParent.isUserLocked()) && childColor != 0);
             mShowNoBackground = !showBackground;
         } else {
             // Only children or parents ever need no background.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 540c391..f8bad05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -33,7 +33,6 @@
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
@@ -43,7 +42,6 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.statusbar.notification.InflationException;
-import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -86,7 +84,7 @@
         public List<SnoozeCriterion> snoozeCriteria;
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
-        private ArraySet<AsyncTask> mRunningTasks = new ArraySet();
+        private Abortable mRunningTask = null;
 
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
@@ -203,13 +201,15 @@
             }
         }
 
-        public int getContrastedColor(Context context, boolean ambient) {
-            int rawColor = ambient ? Notification.COLOR_DEFAULT :
+        public int getContrastedColor(Context context, boolean isLowPriority,
+                int backgroundColor) {
+            int rawColor = isLowPriority ? Notification.COLOR_DEFAULT :
                     notification.getNotification().color;
             if (mCachedContrastColorIsFor == rawColor && mCachedContrastColor != COLOR_INVALID) {
                 return mCachedContrastColor;
             }
-            final int contrasted = NotificationColorUtil.resolveContrastColor(context, rawColor);
+            final int contrasted = NotificationColorUtil.resolveContrastColor(context, rawColor,
+                    backgroundColor);
             mCachedContrastColorIsFor = rawColor;
             mCachedContrastColor = contrasted;
             return mCachedContrastColor;
@@ -218,24 +218,26 @@
         /**
          * Abort all existing inflation tasks
          */
-        public void abortInflation() {
-            for (AsyncTask task : mRunningTasks) {
-                task.cancel(true /* mayInterruptIfRunning */);
+        public void abortTask() {
+            if (mRunningTask != null) {
+                mRunningTask.abort();
+                mRunningTask = null;
             }
-            mRunningTasks.clear();
         }
 
-        public void addInflationTask(AsyncTask asyncInflationTask) {
-            mRunningTasks.add(asyncInflationTask);
+        public void setInflationTask(Abortable abortableTask) {
+            // abort any existing inflation
+            abortTask();
+            mRunningTask = abortableTask;
         }
 
-        public void onInflationTaskFinished(AsyncTask asyncInflationTask) {
-            mRunningTasks.remove(asyncInflationTask);
+        public void onInflationTaskFinished() {
+           mRunningTask = null;
         }
 
         @VisibleForTesting
-        public ArraySet<AsyncTask> getRunningTasks() {
-            return mRunningTasks;
+        public Abortable getRunningTask() {
+            return mRunningTask;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 1375310..23a67e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -95,14 +95,25 @@
 
         /**
          * Called when the guts view have been told to close, typically after an outside
-         * interaction. Returning {@code true} here will prevent the guts view to close.
+         * interaction.
+         *
+         * @param save whether the state should be saved.
+         * @param force whether the guts view should be forced closed regardless of state.
+         * @return if closing the view has been handled.
          */
-        public boolean handleCloseControls(boolean save);
+        public boolean handleCloseControls(boolean save, boolean force);
 
         /**
          * @return whether the notification associated with these guts is set to be removed.
          */
         public boolean willBeRemoved();
+
+        /**
+         * @return whether these guts are a leavebehind (e.g. {@link NotificationSnooze}).
+         */
+        public default boolean isLeavebehind() {
+            return false;
+        }
     }
 
     public interface OnGutsClosedListener {
@@ -125,7 +136,7 @@
             @Override
             public void run() {
                 if (mNeedsFalsingProtection && mExposed) {
-                    closeControls(-1 /* x */, -1 /* y */, false /* save */);
+                    closeControls(-1 /* x */, -1 /* y */, false /* save */, false /* force */);
                 }
             }
         };
@@ -144,6 +155,10 @@
         addView(mGutsContent.getContentView());
     }
 
+    public GutsContent getGutsContent() {
+        return mGutsContent;
+    }
+
     public void resetFalsingCheck() {
         mHandler.removeCallbacks(mFalsingCheck);
         if (mNeedsFalsingProtection && mExposed) {
@@ -197,19 +212,30 @@
         }
     }
 
-    public void closeControls(int x, int y, boolean save) {
+    public void closeControls(boolean leavebehinds, boolean controls, int x, int y, boolean force) {
+        if (mGutsContent != null) {
+            if (mGutsContent.isLeavebehind() && leavebehinds) {
+                closeControls(x, y, true /* save */, force);
+            } else if (!mGutsContent.isLeavebehind() && controls) {
+                closeControls(x, y, true /* save */, force);
+            }
+        }
+    }
+
+    public void closeControls(int x, int y, boolean save, boolean force) {
         if (getWindowToken() == null) {
             if (mClosedListener != null) {
                 mClosedListener.onGutsClosed(this);
             }
             return;
         }
-        if (mGutsContent == null || !mGutsContent.handleCloseControls(save)) {
+
+        if (mGutsContent == null || !mGutsContent.handleCloseControls(save, force)) {
             animateClose(x, y);
-        }
-        setExposed(false, mNeedsFalsingProtection);
-        if (mClosedListener != null) {
-            mClosedListener.onGutsClosed(this);
+            setExposed(false, mNeedsFalsingProtection);
+            if (mClosedListener != null) {
+                mClosedListener.onGutsClosed(this);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 2cf06c2..4feaf5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -62,6 +62,7 @@
     private int mAppUid;
     private List<NotificationChannel> mNotificationChannels;
     private NotificationChannel mSingleNotificationChannel;
+    private boolean mIsSingleDefaultChannel;
     private StatusBarNotification mSbn;
     private int mStartingUserImportance;
 
@@ -113,17 +114,23 @@
         mSbn = sbn;
         mPm = pm;
         mAppSettingsClickListener = onAppSettingsClick;
-        boolean isSingleDefaultChannel = false;
         mStartingUserImportance = startingUserImportance;
+        int numTotalChannels = 1;
+        numTotalChannels = iNotificationManager.getNumNotificationChannelsForPackage(
+                pkg, mAppUid, false /* includeDeleted */);
         if (mNotificationChannels.isEmpty()) {
             throw new IllegalArgumentException("bindNotification requires at least one channel");
         } else  {
             if (mNotificationChannels.size() == 1) {
                 mSingleNotificationChannel = mNotificationChannels.get(0);
-                isSingleDefaultChannel = mSingleNotificationChannel.getId()
-                        .equals(NotificationChannel.DEFAULT_CHANNEL_ID);
+                // Special behavior for the Default channel if no other channels have been defined.
+                mIsSingleDefaultChannel =
+                        (mSingleNotificationChannel.getId()
+                                .equals(NotificationChannel.DEFAULT_CHANNEL_ID) &&
+                        numTotalChannels <= 1);
             } else {
                 mSingleNotificationChannel = null;
+                mIsSingleDefaultChannel = false;
             }
         }
 
@@ -148,19 +155,16 @@
         }
         ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
 
-        int numChannels = 1;
-        numChannels = iNotificationManager.getNumNotificationChannelsForPackage(
-                pkg, mAppUid, false /* includeDeleted */);
-
         String channelsDescText;
         mNumChannelsView = findViewById(R.id.num_channels_desc);
-        if (isSingleDefaultChannel) {
+        if (mIsSingleDefaultChannel) {
             channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
         } else {
             switch (mNotificationChannels.size()) {
                 case 1:
                     channelsDescText = String.format(mContext.getResources().getQuantityString(
-                            R.plurals.notification_num_channels_desc, numChannels), numChannels);
+                            R.plurals.notification_num_channels_desc, numTotalChannels),
+                            numTotalChannels);
                     break;
                 case 2:
                     channelsDescText = mContext.getString(
@@ -185,7 +189,7 @@
             // Multiple channels don't use a channel name for the title.
             channelNameText = mContext.getString(R.string.notification_num_channels,
                     mNotificationChannels.size());
-        } else if (isSingleDefaultChannel) {
+        } else if (mIsSingleDefaultChannel) {
             // If this is the default channel, don't use our channel-specific text.
             channelNameText = mContext.getString(R.string.notification_header_default_channel);
         } else {
@@ -241,7 +245,7 @@
                     (View view) -> {
                         onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
                     });
-            if (numChannels > 1) {
+            if (numTotalChannels > 1) {
                 settingsButton.setText(R.string.notification_all_categories);
             } else {
                 settingsButton.setText(R.string.notification_more_settings);
@@ -327,14 +331,12 @@
     private void updateSecondaryText() {
         final boolean disabled = mSingleNotificationChannel != null &&
                 getSelectedImportance() == IMPORTANCE_NONE;
-        final boolean isDefaultChannel = mSingleNotificationChannel != null &&
-                mSingleNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID);
         if (disabled) {
             mChannelDisabledView.setVisibility(View.VISIBLE);
             mNumChannelsView.setVisibility(View.GONE);
         } else {
             mChannelDisabledView.setVisibility(View.GONE);
-            mNumChannelsView.setVisibility(isDefaultChannel ? View.INVISIBLE : View.VISIBLE);
+            mNumChannelsView.setVisibility(mIsSingleDefaultChannel ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
@@ -393,7 +395,7 @@
     }
 
     @Override
-    public boolean handleCloseControls(boolean save) {
+    public boolean handleCloseControls(boolean save, boolean force) {
         if (save && hasImportanceChanged()) {
             if (mCheckSaveListener != null) {
                 mCheckSaveListener.checkSave(() -> { saveImportance(); });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index cf910a7..d4b8920 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -35,6 +35,7 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.Looper;
 import android.util.Log;
 import android.service.notification.StatusBarNotification;
 import android.view.LayoutInflater;
@@ -108,7 +109,7 @@
         mHorizSpaceForIcon = res.getDimensionPixelSize(R.dimen.notification_menu_icon_size);
         mVertSpaceForIcons = res.getDimensionPixelSize(R.dimen.notification_min_height);
         mIconPadding = res.getDimensionPixelSize(R.dimen.notification_menu_icon_padding);
-        mHandler = new Handler();
+        mHandler = new Handler(Looper.getMainLooper());
         mMenuItems = new ArrayList<>();
         mSnoozeItem = createSnoozeItem(context);
         mInfoItem = createInfoItem(context);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 1bf5238..505cbea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -356,7 +356,8 @@
         }
         float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f;
         if (clampedAmount == fullTransitionAmount) {
-            iconState.useFullTransitionAmount = scrollingFast || expandingAnimated
+            iconState.noAnimations = scrollingFast || expandingAnimated;
+            iconState.useFullTransitionAmount = iconState.noAnimations
                 || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling);
             iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING
                     && fullTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging();
@@ -367,6 +368,7 @@
                 && !ViewState.isAnimatingY(icon))) {
             iconState.cancelAnimations(icon);
             iconState.useFullTransitionAmount = true;
+            iconState.noAnimations = true;
         }
         float transitionAmount;
         if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 8b3d6d9..8830c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -103,6 +103,18 @@
         createOptionViews();
     }
 
+    public boolean isExpanded() {
+        return mExpanded;
+    }
+
+    public void setSnoozeListener(NotificationSwipeActionHelper listener) {
+        mSnoozeListener = listener;
+    }
+
+    public void setStatusBarNotification(StatusBarNotification sbn) {
+        mSbn = sbn;
+    }
+
     private ArrayList<SnoozeOption> getDefaultSnoozeOptions() {
         ArrayList<SnoozeOption> options = new ArrayList<>();
         options.add(createOption(R.string.snooze_option_15_min, 15));
@@ -203,7 +215,7 @@
             final int x = targetLoc[0] - parentLoc[0] + centerX;
             final int y = targetLoc[1] - parentLoc[1] + centerY;
             showSnoozeOptions(false);
-            mGutsContainer.closeControls(x, y, false /* save */);
+            mGutsContainer.closeControls(x, y, false /* save */, false /* force */);
         }
     }
 
@@ -224,29 +236,31 @@
         return this;
     }
 
-    public void setStatusBarNotification(StatusBarNotification sbn) {
-        mSbn = sbn;
-    }
-
     @Override
     public void setGutsParent(NotificationGuts guts) {
         mGutsContainer = guts;
     }
 
-    public void setSnoozeListener(NotificationSwipeActionHelper listener) {
-        mSnoozeListener = listener;
-    }
-
     @Override
-    public boolean handleCloseControls(boolean save) {
-        // When snooze is closed (i.e. there was interaction outside of the notification)
-        // then we commit the snooze action.
-        if (mSnoozeListener != null && mSelectedOption != null) {
+    public boolean handleCloseControls(boolean save, boolean force) {
+        if (mExpanded && !force) {
+            // Collapse expanded state on outside touch
+            showSnoozeOptions(false);
+            return true;
+        } else if (mSnoozeListener != null && mSelectedOption != null) {
+            // Snooze option selected so commit it
             mSnoozing = true;
             mSnoozeListener.snooze(mSbn, mSelectedOption);
             return true;
+        } else {
+            // The view should actually be closed
+            setSelected(mSnoozeOptions.get(0));
+            return false; // Return false here so that guts handles closing the view
         }
-        // The view should be closed
-        return false;
+    }
+
+    @Override
+    public boolean isLeavebehind() {
+        return true;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 7cfc767..f1c26cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -16,19 +16,26 @@
 
 package com.android.systemui.statusbar.notification;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.os.AsyncTask;
+import android.os.CancellationSignal;
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Abortable;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationContentView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.util.Assert;
+
+import java.util.HashMap;
 
 /**
  * A utility that inflates the right kind of contentView based on the state
@@ -116,126 +123,303 @@
     @VisibleForTesting
     void inflateNotificationViews(int reInflateFlags) {
         StatusBarNotification sbn = mRow.getEntry().notification;
-        new AsyncInflationTask(mRow.getContext(), sbn, reInflateFlags).execute();
+        new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority,
+                mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
+                mCallback, mRemoteViewClickHandler).execute();
     }
 
     @VisibleForTesting
-    void inflateNotificationViews(int reInflateFlags,
+    InflationProgress inflateNotificationViews(int reInflateFlags,
             Notification.Builder builder, Context packageContext) {
-        NotificationData.Entry entry = mRow.getEntry();
-        NotificationContentView privateLayout = mRow.getPrivateLayout();
-        NotificationContentView publicLayout = mRow.getPublicLayout();
+        InflationProgress result = createRemoteViews(reInflateFlags, builder, mIsLowPriority,
+                mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
+                mRedactAmbient, packageContext);
+        apply(result, reInflateFlags, mRow, mRedactAmbient, mRemoteViewClickHandler, null);
+        return result;
+    }
 
-        boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
+    private static InflationProgress createRemoteViews(int reInflateFlags,
+            Notification.Builder builder, boolean isLowPriority, boolean isChildInGroup,
+            boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
+            Context packageContext) {
+        InflationProgress result = new InflationProgress();
+        isLowPriority = isLowPriority && !isChildInGroup;
         if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
-            final RemoteViews newContentView = createContentView(builder,
-                    isLowPriority, mUsesIncreasedHeight);
-            if (!compareRemoteViews(newContentView,
-                    entry.cachedContentView)) {
-                View contentViewLocal = newContentView.apply(
-                        packageContext,
-                        privateLayout,
-                        mRemoteViewClickHandler);
-                contentViewLocal.setIsRootNamespace(true);
-                privateLayout.setContractedChild(contentViewLocal);
-            } else {
-                newContentView.reapply(packageContext,
-                        privateLayout.getContractedChild(),
-                        mRemoteViewClickHandler);
-            }
-            entry.cachedContentView = newContentView;
+            result.newContentView = createContentView(builder, isLowPriority, usesIncreasedHeight);
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
-            final RemoteViews newBigContentView = createBigContentView(
-                    builder, isLowPriority);
-            if (newBigContentView != null) {
-                if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
-                    View bigContentViewLocal = newBigContentView.apply(
-                            packageContext,
-                            privateLayout,
-                            mRemoteViewClickHandler);
-                    bigContentViewLocal.setIsRootNamespace(true);
-                    privateLayout.setExpandedChild(bigContentViewLocal);
-                } else {
-                    newBigContentView.reapply(packageContext,
-                            privateLayout.getExpandedChild(),
-                            mRemoteViewClickHandler);
-                }
-            } else if (entry.cachedBigContentView != null) {
-                privateLayout.setExpandedChild(null);
-            }
-            entry.cachedBigContentView = newBigContentView;
-            mRow.setExpandable(newBigContentView != null);
+            result.newExpandedView = createExpandedView(builder, isLowPriority);
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
-            final RemoteViews newHeadsUpContentView =
-                    builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight);
-            if (newHeadsUpContentView != null) {
-                if (!compareRemoteViews(newHeadsUpContentView,
-                        entry.cachedHeadsUpContentView)) {
-                    View headsUpContentViewLocal = newHeadsUpContentView.apply(
-                            packageContext,
-                            privateLayout,
-                            mRemoteViewClickHandler);
-                    headsUpContentViewLocal.setIsRootNamespace(true);
-                    privateLayout.setHeadsUpChild(headsUpContentViewLocal);
-                } else {
-                    newHeadsUpContentView.reapply(packageContext,
-                            privateLayout.getHeadsUpChild(),
-                            mRemoteViewClickHandler);
-                }
-            } else if (entry.cachedHeadsUpContentView != null) {
-                privateLayout.setHeadsUpChild(null);
-            }
-            entry.cachedHeadsUpContentView = newHeadsUpContentView;
+            result.newHeadsUpView = builder.createHeadsUpContentView(usesIncreasedHeadsUpHeight);
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
-            final RemoteViews newPublicNotification
-                    = builder.makePublicContentView();
-            if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
-                View publicContentView = newPublicNotification.apply(
-                        packageContext,
-                        publicLayout,
-                        mRemoteViewClickHandler);
-                publicContentView.setIsRootNamespace(true);
-                publicLayout.setContractedChild(publicContentView);
-            } else {
-                newPublicNotification.reapply(packageContext,
-                        publicLayout.getContractedChild(),
-                        mRemoteViewClickHandler);
-            }
-            entry.cachedPublicContentView = newPublicNotification;
+            result.newPublicView = builder.makePublicContentView();
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
-            final RemoteViews newAmbientNotification = mRedactAmbient
-                    ? builder.makePublicAmbientNotification()
+            result.newAmbientView = redactAmbient ? builder.makePublicAmbientNotification()
                     : builder.makeAmbientNotification();
-            NotificationContentView newParent = mRedactAmbient ? publicLayout : privateLayout;
-            NotificationContentView otherParent = !mRedactAmbient ? publicLayout : privateLayout;
+        }
+        result.packageContext = packageContext;
+        return result;
+    }
 
-            if (newParent.getAmbientChild() == null ||
-                    !compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
-                View ambientContentView = newAmbientNotification.apply(
-                        packageContext,
-                        newParent,
-                        mRemoteViewClickHandler);
-                ambientContentView.setIsRootNamespace(true);
-                newParent.setAmbientChild(ambientContentView);
-                otherParent.setAmbientChild(null);
-            } else {
-                newAmbientNotification.reapply(packageContext,
-                        newParent.getAmbientChild(),
-                        mRemoteViewClickHandler);
+    public static CancellationSignal apply(InflationProgress result, int reInflateFlags,
+            ExpandableNotificationRow row, boolean redactAmbient,
+            RemoteViews.OnClickHandler remoteViewClickHandler,
+            @Nullable InflationCallback callback) {
+        NotificationData.Entry entry = row.getEntry();
+        NotificationContentView privateLayout = row.getPrivateLayout();
+        NotificationContentView publicLayout = row.getPublicLayout();
+        final HashMap<Integer, CancellationSignal> runningInflations = new HashMap<>();
+
+        int flag = FLAG_REINFLATE_CONTENT_VIEW;
+        if ((reInflateFlags & flag) != 0) {
+            boolean isNewView = !compareRemoteViews(result.newContentView, entry.cachedContentView);
+            ApplyCallback applyCallback = new ApplyCallback() {
+                @Override
+                public void setResultView(View v) {
+                    result.inflatedContentView = v;
+                }
+
+                @Override
+                public RemoteViews getRemoteView() {
+                    return result.newContentView;
+                }
+            };
+            applyRemoteView(result, reInflateFlags, flag, row, redactAmbient,
+                    isNewView, remoteViewClickHandler, callback, entry, privateLayout,
+                    privateLayout.getContractedChild(),
+                    runningInflations, applyCallback);
+        }
+
+        flag = FLAG_REINFLATE_EXPANDED_VIEW;
+        if ((reInflateFlags & flag) != 0) {
+            if (result.newExpandedView != null) {
+                boolean isNewView = !compareRemoteViews(result.newExpandedView,
+                        entry.cachedBigContentView);
+                ApplyCallback applyCallback = new ApplyCallback() {
+                    @Override
+                    public void setResultView(View v) {
+                        result.inflatedExpandedView = v;
+                    }
+
+                    @Override
+                    public RemoteViews getRemoteView() {
+                        return result.newExpandedView;
+                    }
+                };
+                applyRemoteView(result, reInflateFlags, flag, row,
+                        redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                        privateLayout, privateLayout.getExpandedChild(), runningInflations,
+                        applyCallback);
             }
-            entry.cachedAmbientContentView = newAmbientNotification;
+        }
+
+        flag = FLAG_REINFLATE_HEADS_UP_VIEW;
+        if ((reInflateFlags & flag) != 0) {
+            if (result.newHeadsUpView != null) {
+                boolean isNewView = !compareRemoteViews(result.newHeadsUpView,
+                        entry.cachedHeadsUpContentView);
+                ApplyCallback applyCallback = new ApplyCallback() {
+                    @Override
+                    public void setResultView(View v) {
+                        result.inflatedHeadsUpView = v;
+                    }
+
+                    @Override
+                    public RemoteViews getRemoteView() {
+                        return result.newHeadsUpView;
+                    }
+                };
+                applyRemoteView(result, reInflateFlags, flag, row,
+                        redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                        privateLayout, privateLayout.getHeadsUpChild(), runningInflations,
+                        applyCallback);
+            }
+        }
+
+        flag = FLAG_REINFLATE_PUBLIC_VIEW;
+        if ((reInflateFlags & flag) != 0) {
+            boolean isNewView = !compareRemoteViews(result.newPublicView,
+                    entry.cachedPublicContentView);
+            ApplyCallback applyCallback = new ApplyCallback() {
+                @Override
+                public void setResultView(View v) {
+                    result.inflatedPublicView = v;
+                }
+
+                @Override
+                public RemoteViews getRemoteView() {
+                    return result.newPublicView;
+                }
+            };
+            applyRemoteView(result, reInflateFlags, flag, row,
+                    redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                    publicLayout, publicLayout.getContractedChild(), runningInflations,
+                    applyCallback);
+        }
+
+        flag = FLAG_REINFLATE_AMBIENT_VIEW;
+        if ((reInflateFlags & flag) != 0) {
+            NotificationContentView newParent = redactAmbient ? publicLayout : privateLayout;
+            boolean isNewView = !canReapplyAmbient(row, redactAmbient) ||
+                    !compareRemoteViews(result.newAmbientView, entry.cachedAmbientContentView);
+            ApplyCallback applyCallback = new ApplyCallback() {
+                @Override
+                public void setResultView(View v) {
+                    result.inflatedAmbientView = v;
+                }
+
+                @Override
+                public RemoteViews getRemoteView() {
+                    return result.newAmbientView;
+                }
+            };
+            applyRemoteView(result, reInflateFlags, flag, row,
+                    redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                    newParent, newParent.getAmbientChild(), runningInflations,
+                    applyCallback);
+        }
+
+        // Let's try to finish, maybe nobody is even inflating anything
+        finishIfDone(result, reInflateFlags, runningInflations, callback, row,
+                redactAmbient);
+        CancellationSignal cancellationSignal = new CancellationSignal();
+        cancellationSignal.setOnCancelListener(
+                () -> runningInflations.values().forEach(CancellationSignal::cancel));
+        return cancellationSignal;
+    }
+
+    private static void applyRemoteView(final InflationProgress result,
+            final int reInflateFlags, int inflationId,
+            final ExpandableNotificationRow row,
+            final boolean redactAmbient, boolean isNewView,
+            RemoteViews.OnClickHandler remoteViewClickHandler,
+            @Nullable final InflationCallback callback, NotificationData.Entry entry,
+            NotificationContentView parentLayout, View existingView,
+            final HashMap<Integer, CancellationSignal> runningInflations,
+            ApplyCallback applyCallback) {
+        RemoteViews.OnViewAppliedListener listener
+                = new RemoteViews.OnViewAppliedListener() {
+
+            @Override
+            public void onViewApplied(View v) {
+                if (isNewView) {
+                    v.setIsRootNamespace(true);
+                    applyCallback.setResultView(v);
+                }
+                runningInflations.remove(inflationId);
+                finishIfDone(result, reInflateFlags, runningInflations, callback, row,
+                        redactAmbient);
+            }
+
+            @Override
+            public void onError(Exception e) {
+                runningInflations.remove(inflationId);
+                handleInflationError(runningInflations, e, entry.notification, callback);
+            }
+        };
+        CancellationSignal cancellationSignal;
+        RemoteViews newContentView = applyCallback.getRemoteView();
+        if (isNewView) {
+            cancellationSignal = newContentView.applyAsync(
+                    result.packageContext,
+                    parentLayout,
+                    null /* executor */,
+                    listener,
+                    remoteViewClickHandler);
+        } else {
+            cancellationSignal = newContentView.reapplyAsync(
+                    result.packageContext,
+                    existingView,
+                    null /* executor */,
+                    listener,
+                    remoteViewClickHandler);
+        }
+        runningInflations.put(inflationId, cancellationSignal);
+    }
+
+    private static void handleInflationError(HashMap<Integer, CancellationSignal> runningInflations,
+            Exception e, StatusBarNotification notification, @Nullable InflationCallback callback) {
+        Assert.isMainThread();
+        runningInflations.values().forEach(CancellationSignal::cancel);
+        if (callback != null) {
+            callback.handleInflationException(notification, e);
         }
     }
 
-    private RemoteViews createBigContentView(Notification.Builder builder,
+    /**
+     * Finish the inflation of the views
+     *
+     * @return true if the inflation was finished
+     */
+    private static boolean finishIfDone(InflationProgress result, int reInflateFlags,
+            HashMap<Integer, CancellationSignal> runningInflations,
+            @Nullable InflationCallback endListener, ExpandableNotificationRow row,
+            boolean redactAmbient) {
+        Assert.isMainThread();
+        NotificationData.Entry entry = row.getEntry();
+        NotificationContentView privateLayout = row.getPrivateLayout();
+        NotificationContentView publicLayout = row.getPublicLayout();
+        if (runningInflations.isEmpty()) {
+            if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+                if (result.inflatedContentView != null) {
+                    privateLayout.setContractedChild(result.inflatedContentView);
+                }
+                entry.cachedContentView = result.newContentView;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+                if (result.inflatedExpandedView != null) {
+                    privateLayout.setExpandedChild(result.inflatedExpandedView);
+                } else if (result.newExpandedView == null) {
+                    privateLayout.setExpandedChild(null);
+                }
+                entry.cachedBigContentView = result.newExpandedView;
+                row.setExpandable(result.newExpandedView != null);
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+                if (result.inflatedHeadsUpView != null) {
+                    privateLayout.setHeadsUpChild(result.inflatedHeadsUpView);
+                } else if (result.newHeadsUpView == null) {
+                    privateLayout.setHeadsUpChild(null);
+                }
+                entry.cachedHeadsUpContentView = result.newHeadsUpView;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+                if (result.inflatedPublicView != null) {
+                    publicLayout.setContractedChild(result.inflatedPublicView);
+                }
+                entry.cachedPublicContentView = result.newPublicView;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+                if (result.inflatedAmbientView != null) {
+                    NotificationContentView newParent = redactAmbient
+                            ? publicLayout : privateLayout;
+                    NotificationContentView otherParent = !redactAmbient
+                            ? publicLayout : privateLayout;
+                    newParent.setAmbientChild(result.inflatedAmbientView);
+                    otherParent.setAmbientChild(null);
+                }
+                entry.cachedAmbientContentView = result.newAmbientView;
+            }
+            if (endListener != null) {
+                endListener.onAsyncInflationFinished(row.getEntry());
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private static RemoteViews createExpandedView(Notification.Builder builder,
             boolean isLowPriority) {
         RemoteViews bigContentView = builder.createBigContentView();
         if (bigContentView != null) {
@@ -249,7 +433,7 @@
         return null;
     }
 
-    private RemoteViews createContentView(Notification.Builder builder,
+    private static RemoteViews createContentView(Notification.Builder builder,
             boolean isLowPriority, boolean useLarge) {
         if (isLowPriority) {
             return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
@@ -258,7 +442,7 @@
     }
 
     // Returns true if the RemoteViews are the same.
-    private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
+    private static boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
         return (a == null && b == null) ||
                 (a != null && b != null
                         && b.getPackage() != null
@@ -272,7 +456,7 @@
     }
 
     public interface InflationCallback {
-        void handleInflationException(StatusBarNotification notification, InflationException e);
+        void handleInflationException(StatusBarNotification notification, Exception e);
         void onAsyncInflationFinished(NotificationData.Entry entry);
     }
 
@@ -286,37 +470,73 @@
         inflateNotificationViews();
     }
 
-    private class AsyncInflationTask extends AsyncTask<Void, Void, Notification.Builder> {
+    private static boolean canReapplyAmbient(ExpandableNotificationRow row, boolean redactAmbient) {
+        NotificationContentView ambientView = redactAmbient ? row.getPublicLayout()
+                : row.getPrivateLayout();            ;
+        return ambientView.getAmbientChild() != null;
+    }
+
+    public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
+            implements InflationCallback, Abortable {
 
         private final StatusBarNotification mSbn;
         private final Context mContext;
         private final int mReInflateFlags;
-        private Context mPackageContext = null;
+        private final boolean mIsLowPriority;
+        private final boolean mIsChildInGroup;
+        private final boolean mUsesIncreasedHeight;
+        private final InflationCallback mCallback;
+        private final boolean mUsesIncreasedHeadsUpHeight;
+        private final boolean mRedactAmbient;
+        private ExpandableNotificationRow mRow;
         private Exception mError;
+        private RemoteViews.OnClickHandler mRemoteViewClickHandler;
+        private CancellationSignal mCancellationSignal;
 
-        private AsyncInflationTask(Context context, StatusBarNotification notification,
-                int reInflateFlags) {
+        private AsyncInflationTask(StatusBarNotification notification,
+                int reInflateFlags, ExpandableNotificationRow row, boolean isLowPriority,
+                boolean isChildInGroup, boolean usesIncreasedHeight,
+                boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
+                InflationCallback callback,
+                RemoteViews.OnClickHandler remoteViewClickHandler) {
+            mRow = row;
+            NotificationData.Entry entry = row.getEntry();
+            entry.setInflationTask(this);
             mSbn = notification;
-            mContext = context;
             mReInflateFlags = reInflateFlags;
-            mRow.getEntry().addInflationTask(this);
+            mContext = mRow.getContext();
+            mIsLowPriority = isLowPriority;
+            mIsChildInGroup = isChildInGroup;
+            mUsesIncreasedHeight = usesIncreasedHeight;
+            mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
+            mRedactAmbient = redactAmbient;
+            mRemoteViewClickHandler = remoteViewClickHandler;
+            mCallback = callback;
         }
 
         @Override
-        protected Notification.Builder doInBackground(Void... params) {
+        protected InflationProgress doInBackground(Void... params) {
             try {
                 final Notification.Builder recoveredBuilder
                         = Notification.Builder.recoverBuilder(mContext,
                         mSbn.getNotification());
-                mPackageContext = mSbn.getPackageContext(mContext);
+                Context packageContext = mSbn.getPackageContext(mContext);
                 Notification notification = mSbn.getNotification();
+                if (mIsLowPriority) {
+                    int backgroundColor = mContext.getColor(
+                            R.color.notification_material_background_low_priority_color);
+                    recoveredBuilder.setBackgroundColorHint(backgroundColor);
+                }
                 if (notification.isMediaNotification()) {
                     MediaNotificationProcessor processor = new MediaNotificationProcessor(mContext,
-                            mPackageContext);
+                            packageContext);
                     processor.setIsLowPriority(mIsLowPriority);
                     processor.processNotification(notification, recoveredBuilder);
                 }
-                return recoveredBuilder;
+                return createRemoteViews(mReInflateFlags,
+                        recoveredBuilder, mIsLowPriority, mIsChildInGroup,
+                        mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
+                        packageContext);
             } catch (Exception e) {
                 mError = e;
                 return null;
@@ -324,34 +544,64 @@
         }
 
         @Override
-        protected void onPostExecute(Notification.Builder builder) {
-            mRow.getEntry().onInflationTaskFinished(this);
+        protected void onPostExecute(InflationProgress result) {
             if (mError == null) {
-                finishInflation(mReInflateFlags, builder, mPackageContext);
+                mCancellationSignal = apply(result, mReInflateFlags, mRow, mRedactAmbient,
+                        mRemoteViewClickHandler, this);
             } else {
                 handleError(mError);
             }
         }
-    }
 
-    private void finishInflation(int reinflationFlags, Notification.Builder builder,
-            Context context) {
-        try {
-            inflateNotificationViews(reinflationFlags, builder, context);
-        } catch (RuntimeException e){
-            handleError(e);
-            return;
+        private void handleError(Exception e) {
+            mRow.getEntry().onInflationTaskFinished();
+            StatusBarNotification sbn = mRow.getStatusBarNotification();
+            final String ident = sbn.getPackageName() + "/0x"
+                    + Integer.toHexString(sbn.getId());
+            Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
+            mCallback.handleInflationException(sbn,
+                    new InflationException("Couldn't inflate contentViews" + e));
         }
-        mRow.onNotificationUpdated();
-        mCallback.onAsyncInflationFinished(mRow.getEntry());
+
+        @Override
+        public void abort() {
+            cancel(true /* mayInterruptIfRunning */);
+            if (mCancellationSignal != null) {
+                mCancellationSignal.cancel();
+            }
+        }
+
+        @Override
+        public void handleInflationException(StatusBarNotification notification, Exception e) {
+            handleError(e);
+        }
+
+        @Override
+        public void onAsyncInflationFinished(NotificationData.Entry entry) {
+            mRow.getEntry().onInflationTaskFinished();
+            mRow.onNotificationUpdated();
+            mCallback.onAsyncInflationFinished(mRow.getEntry());
+        }
     }
 
-    private void handleError(Exception e) {
-        StatusBarNotification sbn = mRow.getStatusBarNotification();
-        final String ident = sbn.getPackageName() + "/0x"
-                + Integer.toHexString(sbn.getId());
-        Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
-        mCallback.handleInflationException(sbn,
-                new InflationException("Couldn't inflate contentViews" + e));
+    private static class InflationProgress {
+        private RemoteViews newContentView;
+        private RemoteViews newHeadsUpView;
+        private RemoteViews newExpandedView;
+        private RemoteViews newAmbientView;
+        private RemoteViews newPublicView;
+
+        private Context packageContext;
+
+        private View inflatedContentView;
+        private View inflatedHeadsUpView;
+        private View inflatedExpandedView;
+        private View inflatedAmbientView;
+        private View inflatedPublicView;
+    }
+
+    private abstract static class ApplyCallback {
+        public abstract void setResultView(View v);
+        public abstract RemoteViews getRemoteView();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java
new file mode 100644
index 0000000..1bfc0cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification;
+
+import android.content.Context;
+import android.support.v4.view.AsyncLayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Abortable;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationData;
+
+/**
+ * An inflater task that asynchronously inflates a ExpandableNotificationRow
+ */
+public class RowInflaterTask implements Abortable, AsyncLayoutInflater.OnInflateFinishedListener {
+    private RowInflationFinishedListener mListener;
+    private NotificationData.Entry mEntry;
+    private boolean mCancelled;
+
+    /**
+     * Inflates a new notificationView. This should not be called twice on this object
+     */
+    public void inflate(Context context, ViewGroup parent, NotificationData.Entry entry,
+            RowInflationFinishedListener listener) {
+        mListener = listener;
+        AsyncLayoutInflater inflater = new AsyncLayoutInflater(context);
+        mEntry = entry;
+        entry.setInflationTask(this);
+        inflater.inflate(R.layout.status_bar_notification_row, parent, this);
+    }
+
+    @Override
+    public void abort() {
+        mCancelled = true;
+    }
+
+    @Override
+    public void onInflateFinished(View view, int resid, ViewGroup parent) {
+        if (!mCancelled) {
+            mEntry.onInflationTaskFinished();
+            mListener.onInflationFinished((ExpandableNotificationRow) view);
+        }
+    }
+
+    public interface RowInflationFinishedListener {
+        void onInflationFinished(ExpandableNotificationRow row);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 1a9a40b..674a61c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -168,7 +168,8 @@
                         distance = mTranslationOnDown + distance;
                         distance = Math.max(0, distance);
                     }
-                    setTranslation(distance, false /* isReset */, false /* animateReset */);
+                    setTranslation(distance, false /* isReset */, false /* animateReset */,
+                            false /* force */);
                 }
                 break;
 
@@ -373,11 +374,12 @@
         targetView.finishAnimation(velocity, mAnimationEndRunnable);
     }
 
-    private void setTranslation(float translation, boolean isReset, boolean animateReset) {
+    private void setTranslation(float translation, boolean isReset, boolean animateReset,
+            boolean force) {
         translation = rightSwipePossible() ? translation : Math.max(0, translation);
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
         float absTranslation = Math.abs(translation);
-        if (translation != mTranslation || isReset) {
+        if (translation != mTranslation || isReset || force) {
             KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
             KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
             float alpha = absTranslation / getMinTranslationAmount();
@@ -392,15 +394,15 @@
             boolean slowAnimation = isReset && isBelowFalsingThreshold();
             if (!isReset) {
                 updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
-                        false, false, false, false);
+                        false, false, force, false);
             } else {
                 updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
-                        animateIcons, slowAnimation, false, forceNoCircleAnimation);
+                        animateIcons, slowAnimation, force, forceNoCircleAnimation);
             }
             updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
-                    animateIcons, slowAnimation, false, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
             updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(),
-                    animateIcons, slowAnimation, false, forceNoCircleAnimation);
+                    animateIcons, slowAnimation, force, forceNoCircleAnimation);
 
             mTranslation = translation;
         }
@@ -508,8 +510,12 @@
     }
 
     public void reset(boolean animate) {
+        reset(animate, false /* force */);
+    }
+
+    public void reset(boolean animate, boolean force) {
         cancelAnimation();
-        setTranslation(0.0f, true, animate);
+        setTranslation(0.0f, true, animate, force);
         mMotionCancelled = true;
         if (mSwipingInProgress) {
             mCallback.onSwipingAborted();
@@ -517,6 +523,10 @@
         }
     }
 
+    public void resetImmediately() {
+        reset(false /* animate */, true /* force */);
+    }
+
     public boolean isSwipingInProgress() {
         return mSwipingInProgress;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 4bfc16b..43c8c28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -94,7 +94,7 @@
  */
 public class NavigationBarFragment extends Fragment implements Callbacks {
 
-    private static final String TAG = "NavigationBar";
+    public static final String TAG = "NavigationBar";
     private static final boolean DEBUG = false;
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 14c16067..930191e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -466,6 +466,7 @@
         public boolean useLinearTransitionAmount;
         public boolean translateContent;
         public int iconColor = StatusBarIconView.NO_COLOR;
+        public boolean noAnimations;
 
         @Override
         public void applyToView(View view) {
@@ -473,7 +474,8 @@
                 StatusBarIconView icon = (StatusBarIconView) view;
                 boolean animate = false;
                 AnimationProperties animationProperties = null;
-                boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation;
+                boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation
+                        && !noAnimations;
                 if (animationsAllowed) {
                     if (justAdded) {
                         super.applyToView(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index f40de79..c52c11a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -529,7 +529,8 @@
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
         }
         closeQs();
-        mStatusBar.dismissPopups();
+        mStatusBar.closeAndSaveGuts(true /* leavebehind */, true /* force */,
+                true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
         mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */,
                 true /* cancelAnimators */);
         mNotificationStackScroller.resetScrollPosition();
@@ -1020,6 +1021,7 @@
         float height = mQsExpansionHeight - overscrollAmount;
         setQsExpansion(height);
         requestPanelHeightUpdate();
+        mNotificationStackScroller.checkSnoozeLeavebehind();
     }
 
     private void setQsExpanded(boolean expanded) {
@@ -1395,6 +1397,7 @@
         animator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                mNotificationStackScroller.resetCheckSnoozeLeavebehind();
                 mQsExpansionAnimator = null;
                 if (onFinishRunnable != null) {
                     onFinishRunnable.run();
@@ -2477,6 +2480,14 @@
         }
     };
 
+    @Override
+    public void setTouchDisabled(boolean disabled) {
+        super.setTouchDisabled(disabled);
+        if (disabled && mAffordanceHelper.isSwipingInProgress() && !mIsLaunchTransitionRunning) {
+            mAffordanceHelper.resetImmediately();
+        }
+    }
+
     public void setDark(boolean dark) {
         mDark = dark;
         mKeyguardStatusView.setDark(dark);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index e86fd48..d342635 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -221,8 +221,11 @@
 
     public void setTouchDisabled(boolean disabled) {
         mTouchDisabled = disabled;
-        if (mTouchDisabled && mTracking) {
-            onTrackingStopped(true /* expanded */);
+        if (mTouchDisabled) {
+            cancelHeightAnimator();
+            if (mTracking) {
+                onTrackingStopped(true /* expanded */);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 5690495..41fb5f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -579,6 +579,7 @@
                     .setComponent(aiaComponent)
                     .setAction(Intent.ACTION_VIEW)
                     .addCategory(Intent.CATEGORY_BROWSABLE)
+                    .addCategory("unique:" + System.currentTimeMillis())
                     .putExtra(Intent.EXTRA_PACKAGE_NAME, appInfo.packageName)
                     .putExtra(Intent.EXTRA_VERSION_CODE, appInfo.versionCode)
                     .putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, pendingIntent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index d29b356..1799bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -35,6 +35,7 @@
 import android.view.animation.PathInterpolator;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
@@ -123,8 +124,8 @@
         mLightBarController = lightBarController;
         mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
 
-        mColorExtractor = new ColorExtractor(context);
-        mColorExtractor.setListener(this);
+        mColorExtractor = Dependency.get(ColorExtractor.class);
+        mColorExtractor.addOnColorsChangedListener(this);
         mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK);
         mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM);
         mNeedsDrawableColorUpdate = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index e1296f5..fa051f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -207,6 +207,7 @@
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.InflationException;
+import com.android.systemui.statusbar.notification.RowInflaterTask;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
@@ -427,6 +428,13 @@
     View mExpandedContents;
     TextView mNotificationPanelDebugText;
 
+    /**
+     * {@code true} if notifications not part of a group should by default be rendered in their
+     * expanded state. If {@code false}, then only the first notification will be expanded if
+     * possible.
+     */
+    private boolean mAlwaysExpandNonGroupedNotification;
+
     // settings
     private QSPanel mQSPanel;
 
@@ -767,6 +775,8 @@
         Resources res = mContext.getResources();
         mScrimSrcModeEnabled = res.getBoolean(R.bool.config_status_bar_scrim_behind_use_src);
         mClearAllEnabled = res.getBoolean(R.bool.config_enableNotificationsClearAll);
+        mAlwaysExpandNonGroupedNotification =
+                res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
 
         DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
         putComponent(StatusBar.class, this);
@@ -851,7 +861,6 @@
 
         // Set up the initial icon state
         int N = iconSlots.size();
-        int viewIndex = 0;
         for (int i=0; i < N; i++) {
             mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
         }
@@ -1598,12 +1607,12 @@
     private void abortExistingInflation(String key) {
         if (mPendingNotifications.containsKey(key)) {
             Entry entry = mPendingNotifications.get(key);
-            entry.abortInflation();
+            entry.abortTask();
             mPendingNotifications.remove(key);
         }
         Entry addedEntry = mNotificationData.get(key);
         if (addedEntry != null) {
-            addedEntry.abortInflation();
+            addedEntry.abortTask();
         }
     }
 
@@ -1620,7 +1629,7 @@
     }
 
     @Override
-    public void handleInflationException(StatusBarNotification notification, InflationException e) {
+    public void handleInflationException(StatusBarNotification notification, Exception e) {
         handleNotificationError(notification, e.getMessage());
     }
 
@@ -3011,8 +3020,9 @@
         mStatusBarWindowManager.setPanelVisible(false);
         mStatusBarWindowManager.setForceStatusBarVisible(false);
 
-        // Close any "App info" popups that might have snuck on-screen
-        dismissPopups();
+        // Close any guts that might be visible
+        closeAndSaveGuts(true /* removeLeavebehind */, true /* force */, true /* removeControls */,
+                -1 /* x */, -1 /* y */, true /* resetMenu */);
 
         runPostCollapseRunnables();
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
@@ -4101,13 +4111,6 @@
             setBarState(StatusBarState.KEYGUARD);
         }
         updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
-        if (!mDeviceInteractive) {
-
-            // If the screen is off already, we need to disable touch events because these might
-            // collapse the panel after we expanded it, and thus we would end up with a blank
-            // Keyguard.
-            mNotificationPanel.setTouchDisabled(true);
-        }
         updatePanelExpansionForKeyguard();
         mLeaveOpenOnKeyguardHide = false;
         if (mDraggedDownRow != null) {
@@ -4637,6 +4640,10 @@
         return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null);
     }
 
+    public View getNavigationBarWindow() {
+        return mNavigationBarView;
+    }
+
     public KeyguardBottomAreaView getKeyguardBottomAreaView() {
         return mKeyguardBottomArea;
     }
@@ -4670,6 +4677,7 @@
     public void onDragDownReset() {
         mStackScroller.setDimmed(true /* dimmed */, true /* animated */);
         mStackScroller.resetScrollPosition();
+        mStackScroller.resetCheckSnoozeLeavebehind();
     }
 
     @Override
@@ -4680,6 +4688,7 @@
     @Override
     public void onTouchSlopExceeded() {
         mStackScroller.removeLongPressCallback();
+        mStackScroller.checkSnoozeLeavebehind();
     }
 
     @Override
@@ -4914,6 +4923,12 @@
         mStackScroller.setAnimationsEnabled(false);
         mVisualStabilityManager.setScreenOn(false);
         updateVisibleToUser();
+
+        // We need to disable touch events because these might
+        // collapse the panel after we expanded it, and thus we would end up with a blank
+        // Keyguard.
+        mNotificationPanel.setTouchDisabled(true);
+        mStatusBarWindow.cancelCurrentTouch();
         if (mLaunchCameraOnFinishedGoingToSleep) {
             mLaunchCameraOnFinishedGoingToSleep = false;
 
@@ -5857,8 +5872,10 @@
             if (!g.willBeRemoved() && !row.isRemoved()) {
                 mStackScroller.onHeightChanged(row, !isPanelFullyCollapsed() /* needsAnimation */);
             }
-            mNotificationGutsExposed = null;
-            mGutsMenuItem = null;
+            if (mNotificationGutsExposed == g) {
+                mNotificationGutsExposed = null;
+                mGutsMenuItem = null;
+            }
         });
 
         View gutsView = item.getGutsView();
@@ -5954,7 +5971,8 @@
         final int centerY = done.getHeight() / 2;
         final int x = doneLocation[0] - rowLocation[0] + centerX;
         final int y = doneLocation[1] - rowLocation[1] + centerY;
-        dismissPopups(x, y);
+        closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
+                true /* removeControls */, x, y, true /* resetMenu */);
     }
 
     protected SwipeHelper.LongPressListener getNotificationLongClicker() {
@@ -5974,6 +5992,12 @@
                 if (row.isDark()) {
                     return false;
                 }
+                if (row.areGutsExposed()) {
+                    closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
+                            true /* removeControls */, -1 /* x */, -1 /* y */,
+                            true /* resetMenu */);
+                    return false;
+                }
                 bindGuts(row, item);
                 NotificationGuts guts = row.getGuts();
 
@@ -5983,12 +6007,6 @@
                     return false;
                 }
 
-                // Already showing?
-                if (guts.getVisibility() == View.VISIBLE) {
-                    dismissPopups(x, y);
-                    return false;
-                }
-
                 mMetricsLogger.action(MetricsEvent.ACTION_NOTE_CONTROLS);
 
                 // ensure that it's laid but not visible until actually laid out
@@ -6002,8 +6020,9 @@
                                     + "window");
                             return;
                         }
-                        dismissPopups(-1 /* x */, -1 /* y */, false /* resetMenu */,
-                                false /* animate */);
+                        closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
+                                true /* removeControls */, -1 /* x */, -1 /* y */,
+                                false /* resetMenu */);
                         guts.setVisibility(View.VISIBLE);
                         final double horz = Math.max(guts.getWidth() - x, x);
                         final double vert = Math.max(guts.getHeight() - y, y);
@@ -6043,20 +6062,23 @@
         return mNotificationGutsExposed;
     }
 
-    public void dismissPopups() {
-        dismissPopups(-1 /* x */, -1 /* y */, true /* resetMenu */, false /* animate */);
-    }
-
-    private void dismissPopups(int x, int y) {
-        dismissPopups(x, y, true /* resetMenu */, false /* animate */);
-    }
-
-    public void dismissPopups(int x, int y, boolean resetMenu, boolean animate) {
+    /**
+     * Closes guts or notification menus that might be visible and saves any changes.
+     *
+     * @param removeLeavebehinds true if leavebehinds (e.g. snooze) should be closed.
+     * @param force true if guts should be closed regardless of state (used for snooze only).
+     * @param removeControls true if controls (e.g. info) should be closed.
+     * @param x if closed based on touch location, this is the x touch location.
+     * @param y if closed based on touch location, this is the y touch location.
+     * @param resetMenu if any notification menus that might be revealed should be closed.
+     */
+    public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls,
+            int x, int y, boolean resetMenu) {
         if (mNotificationGutsExposed != null) {
-            mNotificationGutsExposed.closeControls(x, y, true /* save */);
+            mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force);
         }
         if (resetMenu) {
-            mStackScroller.resetExposedMenuView(animate, true /* force */);
+            mStackScroller.resetExposedMenuView(false /* animate */, true /* force */);
         }
     }
 
@@ -6234,50 +6256,57 @@
                 entry.notification.getUser().getIdentifier());
 
         final StatusBarNotification sbn = entry.notification;
-        ExpandableNotificationRow row;
         if (entry.row != null) {
-            row = entry.row;
             entry.reset();
+            updateNotification(entry, pmUser, sbn, entry.row);
         } else {
-            // create the row view
-            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            row = (ExpandableNotificationRow) inflater.inflate(R.layout.status_bar_notification_row,
-                    parent, false);
-            row.setExpansionLogger(this, entry.notification.getKey());
-            row.setGroupManager(mGroupManager);
-            row.setHeadsUpManager(mHeadsUpManager);
-            row.setRemoteInputController(mRemoteInputController);
-            row.setOnExpandClickListener(this);
-            row.setRemoteViewClickHandler(mOnClickHandler);
-            row.setInflationCallback(this);
-
-            // Get the app name.
-            // Note that Notification.Builder#bindHeaderAppName has similar logic
-            // but since this field is used in the guts, it must be accurate.
-            // Therefore we will only show the application label, or, failing that, the
-            // package name. No substitutions.
-            final String pkg = sbn.getPackageName();
-            String appname = pkg;
-            try {
-                final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES
-                                | PackageManager.MATCH_DISABLED_COMPONENTS);
-                if (info != null) {
-                    appname = String.valueOf(pmUser.getApplicationLabel(info));
-                }
-            } catch (NameNotFoundException e) {
-                // Do nothing
-            }
-            row.setAppName(appname);
-            row.setOnDismissRunnable(() ->
-                    performRemoveNotification(row.getStatusBarNotification()));
-            row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-            if (ENABLE_REMOTE_INPUT) {
-                row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
-            }
+            new RowInflaterTask().inflate(mContext, parent, entry,
+                    row -> {
+                        bindRow(entry, pmUser, sbn, row);
+                        updateNotification(entry, pmUser, sbn, row);
+                    });
         }
 
+    }
+
+    private void bindRow(Entry entry, PackageManager pmUser,
+            StatusBarNotification sbn, ExpandableNotificationRow row) {
+        row.setExpansionLogger(this, entry.notification.getKey());
+        row.setGroupManager(mGroupManager);
+        row.setHeadsUpManager(mHeadsUpManager);
+        row.setRemoteInputController(mRemoteInputController);
+        row.setOnExpandClickListener(this);
+        row.setRemoteViewClickHandler(mOnClickHandler);
+        row.setInflationCallback(this);
+
+        // Get the app name.
+        // Note that Notification.Builder#bindHeaderAppName has similar logic
+        // but since this field is used in the guts, it must be accurate.
+        // Therefore we will only show the application label, or, failing that, the
+        // package name. No substitutions.
+        final String pkg = sbn.getPackageName();
+        String appname = pkg;
+        try {
+            final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
+                    PackageManager.MATCH_UNINSTALLED_PACKAGES
+                            | PackageManager.MATCH_DISABLED_COMPONENTS);
+            if (info != null) {
+                appname = String.valueOf(pmUser.getApplicationLabel(info));
+            }
+        } catch (NameNotFoundException e) {
+            // Do nothing
+        }
+        row.setAppName(appname);
+        row.setOnDismissRunnable(() ->
+                performRemoveNotification(row.getStatusBarNotification()));
+        row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+        if (ENABLE_REMOTE_INPUT) {
+            row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+        }
+    }
+
+    private void updateNotification(Entry entry, PackageManager pmUser,
+            StatusBarNotification sbn, ExpandableNotificationRow row) {
         row.setNeedsRedaction(needsRedaction(entry));
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
         row.setIsLowPriority(isLowPriority);
@@ -6582,7 +6611,8 @@
         if (mVisible != visible) {
             mVisible = visible;
             if (!visible) {
-                dismissPopups();
+                closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
+                        true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
             }
         }
         updateVisibleToUser();
@@ -6681,13 +6711,18 @@
         while(!stack.isEmpty()) {
             ExpandableNotificationRow row = stack.pop();
             NotificationData.Entry entry = row.getEntry();
-            boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
-            if (onKeyguard) {
-                row.setOnKeyguard(true);
-            } else {
-                row.setOnKeyguard(false);
-                row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
+            boolean isChildNotification =
+                    mGroupManager.isChildInGroupWithSummary(entry.notification);
+
+            row.setOnKeyguard(onKeyguard);
+
+            if (!onKeyguard) {
+                // If mAlwaysExpandNonGroupedNotification is false, then only expand the
+                // very first notification and if it's not a child of grouped notifications.
+                row.setSystemExpanded(mAlwaysExpandNonGroupedNotification
+                        || (visibleNotifications == 0 && !isChildNotification));
             }
+
             entry.row.setShowAmbient(isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
@@ -6702,7 +6737,7 @@
                 if (wasGone) {
                     entry.row.setVisibility(View.VISIBLE);
                 }
-                if (!childNotification && !entry.row.isRemoved()) {
+                if (!isChildNotification && !entry.row.isRemoved()) {
                     if (wasGone) {
                         // notify the scroller of a child addition
                         mStackScroller.generateAddAnimation(entry.row,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 1a09d75..26e007c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -37,6 +37,7 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.view.ActionMode;
+import android.view.InputDevice;
 import android.view.InputQueue;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -84,6 +85,8 @@
     private ActionMode mFloatingActionMode;
     private FloatingToolbar mFloatingToolbar;
     private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
+    private boolean mTouchCancelled;
+    private boolean mTouchActive;
 
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -239,10 +242,20 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
-        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN
-                && mNotificationPanel.isFullyCollapsed()) {
+        boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+        if (isDown && mNotificationPanel.isFullyCollapsed()) {
             mNotificationPanel.startExpandLatencyTracking();
         }
+        if (isDown) {
+            mTouchActive = true;
+            mTouchCancelled = false;
+        } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
+                || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
+            mTouchActive = false;
+        }
+        if (mTouchCancelled) {
+            return false;
+        }
         mFalsingManager.onTouchEvent(ev, getWidth(), getHeight());
         if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
             // Disallow new pointers while the brightness mirror is visible. This is so that you
@@ -252,7 +265,7 @@
                 return false;
             }
         }
-        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+        if (isDown) {
             mStackScrollLayout.closeControlsIfOutsideTouch(ev);
         }
         if (mService.isDozing()) {
@@ -349,6 +362,18 @@
         }
     }
 
+    public void cancelCurrentTouch() {
+        if (mTouchActive) {
+            final long now = SystemClock.uptimeMillis();
+            MotionEvent event = MotionEvent.obtain(now, now,
+                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+            dispatchTouchEvent(event);
+            event.recycle();
+            mTouchCancelled = true;
+        }
+    }
+
     public class LayoutParams extends FrameLayout.LayoutParams {
 
         public boolean ignoreRightInset;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index fcb7289..efbf76b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -17,7 +17,10 @@
 
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -28,16 +31,23 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.os.AsyncTask;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.security.KeyChain;
+import android.security.KeyChain.KeyChainConnection;
+import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.settings.CurrentUserTracker;
 
@@ -59,6 +69,8 @@
 
     private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
 
+    private static final int CA_CERT_LOADING_RETRY_TIME_IN_MS = 30_000;
+
     private final Context mContext;
     private final ConnectivityManager mConnectivityManager;
     private final IConnectivityManager mConnectivityManagerService;
@@ -73,6 +85,10 @@
     private int mCurrentUserId;
     private int mVpnUserId;
 
+    // Key: userId, Value: whether the user has CACerts installed
+    // Needs to be cached here since the query has to be asynchronous
+    private ArrayMap<Integer, Boolean> mHasCACerts = new ArrayMap<Integer, Boolean>();
+
     public SecurityControllerImpl(Context context) {
         super(context);
         mContext = context;
@@ -86,6 +102,11 @@
         mUserManager = (UserManager)
                 context.getSystemService(Context.USER_SERVICE);
 
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
+        context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null,
+                new Handler(Dependency.get(Dependency.BG_LOOPER)));
+
         // TODO: re-register network callback on user change.
         mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
         onUserSwitched(ActivityManager.getCurrentUser());
@@ -218,14 +239,16 @@
 
     @Override
     public boolean hasCACertInCurrentUser() {
-        //TODO: implement
-        return false;
+        Boolean hasCACerts = mHasCACerts.get(mCurrentUserId);
+        return hasCACerts != null && hasCACerts.booleanValue();
     }
 
     @Override
     public boolean hasCACertInWorkProfile() {
-        //TODO: implement
-        return false;
+        int userId = getWorkProfileUserId(mCurrentUserId);
+        if (userId == UserHandle.USER_NULL) return false;
+        Boolean hasCACerts = mHasCACerts.get(userId);
+        return hasCACerts != null && hasCACerts.booleanValue();
     }
 
     @Override
@@ -256,9 +279,16 @@
         } else {
             mVpnUserId = mCurrentUserId;
         }
+        refreshCACerts();
         fireCallbacks();
     }
 
+    private void refreshCACerts() {
+        new CACertLoader().execute(mCurrentUserId);
+        int workProfileId = getWorkProfileUserId(mCurrentUserId);
+        if (workProfileId != UserHandle.USER_NULL) new CACertLoader().execute(workProfileId);
+    }
+
     private String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
         if (cfg.legacy) {
             return mContext.getString(R.string.legacy_vpn_name);
@@ -348,4 +378,39 @@
             fireCallbacks();
         };
     };
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override public void onReceive(Context context, Intent intent) {
+            if (KeyChain.ACTION_TRUST_STORE_CHANGED.equals(intent.getAction())) {
+                refreshCACerts();
+            }
+        }
+    };
+
+    protected class CACertLoader extends AsyncTask<Integer, Void, Pair<Integer, Boolean> > {
+
+        @Override
+        protected Pair<Integer, Boolean> doInBackground(Integer... userId) {
+            try (KeyChainConnection conn = KeyChain.bindAsUser(mContext,
+                                                               UserHandle.of(userId[0]))) {
+                boolean hasCACerts = !(conn.getService().getUserCaAliases().getList().isEmpty());
+                return new Pair<Integer, Boolean>(userId[0], hasCACerts);
+            } catch (RemoteException | InterruptedException | AssertionError e) {
+                Log.i(TAG, e.getMessage());
+                new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(
+                        () -> new CACertLoader().execute(userId[0]),
+                        CA_CERT_LOADING_RETRY_TIME_IN_MS);
+                return new Pair<Integer, Boolean>(userId[0], null);
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Pair<Integer, Boolean> result) {
+            if (DEBUG) Log.d(TAG, "onPostExecute " + result);
+            if (result.second != null) {
+                mHasCACerts.put(result.first, result.second);
+                fireCallbacks();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index fe249a6..79926fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -19,6 +19,7 @@
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.drawable.ColorDrawable;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
@@ -28,7 +29,6 @@
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
 import android.widget.TextView;
-
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.CrossFadeHelper;
@@ -66,8 +66,9 @@
     private final HybridGroupManager mHybridGroupManager;
     private int mChildPadding;
     private int mDividerHeight;
-    private int mMaxNotificationHeight;
+    private float mDividerAlpha;
     private int mNotificationHeaderMargin;
+
     private int mNotificatonTopPadding;
     private float mCollapsedBottompadding;
     private ViewInvertHelper mOverflowInvertHelper;
@@ -81,6 +82,11 @@
     private boolean mNeverAppliedGroupState;
     private int mHeaderHeight;
 
+    /**
+     * Whether or not individual notifications that are part of this container will have shadows.
+     */
+    private boolean mEnableShadowOnChildNotifications;
+
     private NotificationHeaderView mNotificationHeader;
     private NotificationViewWrapper mNotificationHeaderWrapper;
     private NotificationHeaderView mNotificationHeaderLowPriority;
@@ -92,6 +98,9 @@
     private OnClickListener mHeaderClickListener;
     private boolean mShowingNormalHeader;
 
+    private boolean mShowDividersWhenExpanded;
+    private boolean mHideDividersDuringExpand;
+
     public NotificationChildrenContainer(Context context) {
         this(context, null);
     }
@@ -112,19 +121,25 @@
     }
 
     private void initDimens() {
-        mChildPadding = getResources().getDimensionPixelSize(
-                R.dimen.notification_children_padding);
-        mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
-                R.dimen.notification_divider_height));
-        mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.notification_header_height);
-        mMaxNotificationHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_max_height);
-        mNotificationHeaderMargin = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_top);
-        mNotificatonTopPadding = getResources().getDimensionPixelSize(
+        Resources res = getResources();
+        mChildPadding = res.getDimensionPixelSize(R.dimen.notification_children_padding);
+        mDividerHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_divider_height);
+        mDividerAlpha = res.getFloat(R.dimen.notification_divider_alpha);
+        mHeaderHeight = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_header_height);
+        mNotificationHeaderMargin = res.getDimensionPixelSize(
+                R.dimen.notification_children_container_margin_top);
+        mNotificatonTopPadding = res.getDimensionPixelSize(
                 R.dimen.notification_children_container_top_padding);
-        mCollapsedBottompadding = getResources().getDimensionPixelSize(
+        mCollapsedBottompadding = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_bottom);
+        mEnableShadowOnChildNotifications =
+                res.getBoolean(R.bool.config_enableShadowOnChildNotifications);
+        mShowDividersWhenExpanded =
+                res.getBoolean(R.bool.config_showDividersWhenGroupNotificationExpanded);
+        mHideDividersDuringExpand =
+                res.getBoolean(R.bool.config_hideDividersDuringExpand);
     }
 
     @Override
@@ -536,7 +551,7 @@
             childState.hidden = false;
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
-            childState.zTranslation = childrenExpanded
+            childState.zTranslation = childrenExpanded && mEnableShadowOnChildNotifications
                     ? mContainingNotification.getTranslationZ()
                     : 0;
             childState.dimmed = parentState.dimmed;
@@ -638,7 +653,9 @@
             expandFraction = getGroupExpandFraction();
         }
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
@@ -648,7 +665,7 @@
             View divider = mDividers.get(i);
             tmpState.initFrom(divider);
             tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
-            float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+            float alpha = mChildrenExpanded && viewState.alpha != 0 ? mDividerAlpha : 0;
             if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
                 alpha = NotificationUtils.interpolate(0, 0.5f,
                         Math.min(viewState.alpha, expandFraction));
@@ -712,7 +729,9 @@
         ViewState tmpState = new ViewState();
         float expandFraction = getGroupExpandFraction();
         final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
-                || mContainingNotification.isGroupExpansionChanging();
+                || (mChildrenExpanded && mShowDividersWhenExpanded)
+                || (mContainingNotification.isGroupExpansionChanging()
+                && !mHideDividersDuringExpand);
         for (int i = childCount - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 94b6aaa..0656d73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -77,6 +77,7 @@
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationGuts;
 import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.NotificationSnooze;
 import com.android.systemui.statusbar.StackScrollerDecorView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.FakeShadowView;
@@ -240,6 +241,7 @@
     private NotificationMenuRowPlugin mCurrMenuRow;
     private View mTranslatingParentView;
     private View mMenuExposedView;
+    boolean mCheckForLeavebehind;
 
     /**
      * Should in this touch motion only be scrolling allowed? It's true when the scroller was
@@ -1314,6 +1316,22 @@
                 && !mDisallowDismissInThisMotion) {
             horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
         }
+
+        // Check if we need to clear any snooze leavebehinds
+        NotificationGuts guts = mStatusBar.getExposedGuts();
+        if (guts != null && !isTouchInView(ev, guts)
+                && guts.getGutsContent() instanceof NotificationSnooze) {
+            NotificationSnooze ns = (NotificationSnooze) guts.getGutsContent();
+            if ((ns.isExpanded() && isCancelOrUp)
+                    || (!horizontalSwipeWantsIt && scrollerWantsIt)) {
+                // If the leavebehind is expanded we clear it on the next up event, otherwise we
+                // clear it on the next non-horizontal swipe or expand event.
+                checkSnoozeLeavebehind();
+            }
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            mCheckForLeavebehind = true;
+        }
         return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
     }
 
@@ -1433,6 +1451,8 @@
                         // existing overScroll, we have to scroll the view
                         customOverScrollBy((int) scrollAmount, mOwnScrollY,
                                 range, getHeight() / 2);
+                        // If we're scrolling, leavebehinds should be dismissed
+                        checkSnoozeLeavebehind();
                     }
                 }
                 break;
@@ -2463,6 +2483,18 @@
                 && !mDisallowDismissInThisMotion) {
             swipeWantsIt = mSwipeHelper.onInterceptTouchEvent(ev);
         }
+        // Check if we need to clear any snooze leavebehinds
+        boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
+        NotificationGuts guts = mStatusBar.getExposedGuts();
+        if (!isTouchInView(ev, guts) && isUp && !swipeWantsIt && !expandWantsIt
+                && !scrollWantsIt) {
+            mCheckForLeavebehind = false;
+            mStatusBar.closeAndSaveGuts(true /* removeLeavebehind */, false /* force */,
+                    false /* removeControls */, -1 /* x */, -1 /* y */, false /* resetMenu */);
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            mCheckForLeavebehind = true;
+        }
         return swipeWantsIt || scrollWantsIt || expandWantsIt || super.onInterceptTouchEvent(ev);
     }
 
@@ -3292,13 +3324,27 @@
         return Math.max(mMaxLayoutHeight - mContentHeight, 0);
     }
 
+    public void checkSnoozeLeavebehind() {
+        if (mCheckForLeavebehind) {
+            mStatusBar.closeAndSaveGuts(true /* removeLeavebehind */, false /* force */,
+                    false /* removeControls */, -1 /* x */, -1 /* y */, false /* resetMenu */);
+            mCheckForLeavebehind = false;
+        }
+    }
+
+    public void resetCheckSnoozeLeavebehind() {
+        mCheckForLeavebehind = true;
+    }
+
     public void onExpansionStarted() {
         mIsExpansionChanging = true;
         mAmbientState.setExpansionChanging(true);
+        checkSnoozeLeavebehind();
     }
 
     public void onExpansionStopped() {
         mIsExpansionChanging = false;
+        resetCheckSnoozeLeavebehind();
         mAmbientState.setExpansionChanging(false);
         if (!mIsExpanded) {
             setOwnScrollY(0);
@@ -4300,6 +4346,8 @@
                 // of the panel early.
                 handleChildDismissed(view);
             }
+            mStatusBar.closeAndSaveGuts(true /* removeLeavebehind */, false /* force */,
+                    false /* removeControls */, -1 /* x */, -1 /* y */, false /* resetMenu */);
             handleMenuCoveredOrDismissed();
         }
 
@@ -4382,29 +4430,19 @@
         public void closeControlsIfOutsideTouch(MotionEvent ev) {
             NotificationGuts guts = mStatusBar.getExposedGuts();
             View view = null;
-            int height = 0;
-            if (guts != null) {
-                // Checking guts
+            if (guts != null && !guts.getGutsContent().isLeavebehind()) {
+                // Only close visible guts if they're not a leavebehind.
                 view = guts;
-                height = guts.getActualHeight();
             } else if (mCurrMenuRow != null && mCurrMenuRow.isMenuVisible()
                     && mTranslatingParentView != null) {
                 // Checking menu
                 view = mTranslatingParentView;
-                height = ((ExpandableView) mTranslatingParentView).getActualHeight();
             }
-            if (view != null) {
-                final int rx = (int) ev.getRawX();
-                final int ry = (int) ev.getRawY();
-
-                view.getLocationOnScreen(mTempInt2);
-                final int x = mTempInt2[0];
-                final int y = mTempInt2[1];
-                Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
-                if (!rect.contains(rx, ry)) {
-                    // Touch was outside visible guts / meny notification, close what's visible
-                    mStatusBar.dismissPopups(-1, -1, true /* resetMenu */, true /* animate */);
-                }
+            if (view != null && !isTouchInView(ev, view)) {
+                // Touch was outside visible guts / menu notification, close what's visible
+                mStatusBar.closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
+                        true /* removeControls */, -1 /* x */, -1 /* y */, false /* resetMenu */);
+                resetExposedMenuView(true /* animate */, true /* force */);
             }
         }
 
@@ -4428,6 +4466,23 @@
         }
     }
 
+    private boolean isTouchInView(MotionEvent ev, View view) {
+        if (view == null) {
+            return false;
+        }
+        final int height = (view instanceof ExpandableView)
+                ? ((ExpandableView) view).getActualHeight()
+                : view.getHeight();
+        final int rx = (int) ev.getRawX();
+        final int ry = (int) ev.getRawY();
+        view.getLocationOnScreen(mTempInt2);
+        final int x = mTempInt2[0];
+        final int y = mTempInt2[1];
+        Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
+        boolean ret = rect.contains(rx, ry);
+        return ret;
+    }
+
     private void updateContinuousShadowDrawing() {
         boolean continuousShadowUpdate = mAnimationRunning
                 || !mAmbientState.getDraggedViews().isEmpty();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
new file mode 100644
index 0000000..af99236
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.tuner;
+
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+/**
+ * Version of Space that can be resized by a tunable setting.
+ */
+public class TunablePadding implements Tunable {
+
+    public static final int FLAG_START = 1;
+    public static final int FLAG_END = 2;
+    public static final int FLAG_TOP = 4;
+    public static final int FLAG_BOTTOM = 8;
+
+    private final int mFlags;
+    private final View mView;
+    private final int mDefaultSize;
+    private final float mDensity;
+
+    private TunablePadding(String key, int def, int flags, View view) {
+        mDefaultSize = def;
+        mFlags = flags;
+        mView = view;
+        DisplayMetrics metrics = new DisplayMetrics();
+        view.getContext().getSystemService(WindowManager.class)
+                .getDefaultDisplay().getMetrics(metrics);
+        mDensity = metrics.density;
+        Dependency.get(TunerService.class).addTunable(this, key);
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        int dimen = mDefaultSize;
+        if (newValue != null) {
+            dimen = (int) (Integer.parseInt(newValue) * mDensity);
+        }
+        int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
+        int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
+        mView.setPadding(getPadding(dimen, left), getPadding(dimen, FLAG_TOP),
+                getPadding(dimen, right), getPadding(dimen, FLAG_BOTTOM));
+    }
+
+    private int getPadding(int dimen, int flag) {
+        return ((mFlags & flag) != 0) ? dimen : 0;
+    }
+
+    public void destroy() {
+        Dependency.get(TunerService.class).removeTunable(this);
+    }
+
+    // Exists for easy injecting in tests.
+    public static class TunablePaddingService {
+        public TunablePadding add(View view, String key, int defaultSize, int flags) {
+            if (view == null) {
+                throw new IllegalArgumentException();
+            }
+            return new TunablePadding(key, defaultSize, flags, view);
+        }
+    }
+
+    public static TunablePadding addTunablePadding(View view, String key, int defaultSize,
+            int flags) {
+        return Dependency.get(TunablePaddingService.class).add(view, key, defaultSize, flags);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index cd85a76..ae8afe4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -30,6 +30,7 @@
     public static String SCREENSHOTS = "SCN";
     public static String GENERAL     = "GEN";
     public static String STORAGE     = "DSK";
+    public static String TVPIP       = "TPP";
 
     @VisibleForTesting
     static void createAll(Context context) {
@@ -55,6 +56,15 @@
                                 ? NotificationManager.IMPORTANCE_DEFAULT
                                 : NotificationManager.IMPORTANCE_LOW)
                 ));
+        if (isTv(context)) {
+            // TV specific notification channel for TV PIP controls.
+            // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest
+            // priority, so it can be shown in all times.
+            nm.createNotificationChannel(new NotificationChannel(
+                    TVPIP,
+                    context.getString(R.string.notification_channel_tv_pip),
+                    NotificationManager.IMPORTANCE_MAX));
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index b8b046b..1f674e0 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,6 +18,7 @@
 
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.ObjectAnimator;
@@ -59,6 +60,7 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.view.Window;
 import android.view.WindowManager;
@@ -73,6 +75,7 @@
 
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.HardwareUiLayout;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.VolumeDialogController;
@@ -199,53 +202,37 @@
                 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
         mDialog.setCanceledOnTouchOutside(true);
         final Resources res = mContext.getResources();
-        final WindowManager.LayoutParams lp = mWindow.getAttributes();
-        lp.type = mWindowType;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
-        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-        lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
-        lp.gravity = Gravity.TOP;
-        lp.windowAnimations = -1;
-        mWindow.setAttributes(lp);
         mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
 
-        mDialog.setContentView(R.layout.volume_dialog);
-        mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
-        mDialogView.setOnHoverListener(new View.OnHoverListener() {
-            @Override
-            public boolean onHover(View v, MotionEvent event) {
-                int action = event.getActionMasked();
-                mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
-                        || (action == MotionEvent.ACTION_HOVER_MOVE);
-                rescheduleTimeoutH();
-                return true;
-            }
+        mDialog.setContentView(R.layout.volume_dialog_wrapped);
+        mDialogView = mDialog.findViewById(R.id.volume_dialog);
+        mDialogView.setOnHoverListener((v, event) -> {
+            int action = event.getActionMasked();
+            mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+                    || (action == MotionEvent.ACTION_HOVER_MOVE);
+            rescheduleTimeoutH();
+            return true;
         });
-        mDialogContentView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog_content);
-        mDialogRowsView = (ViewGroup) mDialogContentView.findViewById(R.id.volume_dialog_rows);
+        mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
+        mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
         mExpanded = false;
-        mExpandButton = (ImageButton) mDialogView.findViewById(R.id.volume_expand_button);
+        mExpandButton = mDialogView.findViewById(R.id.volume_expand_button);
         mExpandButton.setOnClickListener(mClickExpand);
 
         mExpandButton.setVisibility(
                 AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE);
-        updateWindowWidthH();
         updateExpandButtonH();
 
-        mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView, mExpandButton,
-                new VolumeDialogMotion.Callback() {
-                    @Override
-                    public void onAnimatingChanged(boolean animating) {
-                        if (animating) return;
-                        if (mPendingStateChanged) {
-                            mHandler.sendEmptyMessage(H.STATE_CHANGED);
-                            mPendingStateChanged = false;
-                        }
-                        if (mPendingRecheckAll) {
-                            mHandler.sendEmptyMessage(H.RECHECK_ALL);
-                            mPendingRecheckAll = false;
-                        }
+        mMotion = new VolumeDialogMotion(mDialog, (View) mDialogView.getParent(),
+                mDialogContentView, mExpandButton, animating -> {
+                    if (animating) return;
+                    if (mPendingStateChanged) {
+                        mHandler.sendEmptyMessage(H.STATE_CHANGED);
+                        mPendingStateChanged = false;
+                    }
+                    if (mPendingRecheckAll) {
+                        mHandler.sendEmptyMessage(H.RECHECK_ALL);
+                        mPendingRecheckAll = false;
                     }
                 });
 
@@ -270,11 +257,20 @@
             addExistingRows();
         }
         mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
-        mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
+        mZenFooter = mDialog.findViewById(R.id.volume_zen_footer);
         mZenFooter.init(mZenModeController);
-        mZenPanel = (TunerZenModePanel) mDialog.findViewById(R.id.tuner_zen_mode_panel);
+        mZenPanel = mDialog.findViewById(R.id.tuner_zen_mode_panel);
         mZenPanel.init(mZenModeController);
         mZenPanel.setCallback(mZenPanelCallback);
+
+        final WindowManager.LayoutParams lp = mWindow.getAttributes();
+        lp.width = MATCH_PARENT;
+        lp.height = MATCH_PARENT;
+        lp.type = mWindowType;
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+        lp.windowAnimations = -1;
+        mWindow.setAttributes(lp);
     }
 
     @Override
@@ -288,20 +284,6 @@
         return ColorStateList.valueOf(mContext.getColor(colorResId));
     }
 
-    private void updateWindowWidthH() {
-        final ViewGroup.LayoutParams lp = mDialogView.getLayoutParams();
-        final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
-        if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
-        int w = dm.widthPixels;
-        final int max = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
-        if (w > max) {
-            w = max;
-        }
-        lp.width = w;
-        mDialogView.setLayoutParams(lp);
-    }
-
     public void setStreamImportant(int stream, boolean important) {
         mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
     }
@@ -542,10 +524,8 @@
     }
 
     private void updateDialogBottomMarginH() {
-        final long diff = System.currentTimeMillis() - mCollapseTime;
-        final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
         final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
-        final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
+        final int bottomMargin =
                 mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
         if (bottomMargin != mlp.bottomMargin) {
             if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
@@ -575,7 +555,7 @@
         TransitionManager.endTransitions(mDialogView);
         final VolumeRow activeRow = getActiveRow();
         if (!dismissing) {
-            mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT);
+            mWindow.setLayout(mWindow.getAttributes().width, MATCH_PARENT);
             TransitionManager.beginDelayedTransition(mDialogView, getTransistion());
         }
         updateRowsH(activeRow);
@@ -637,7 +617,7 @@
             final boolean isActive = row == activeRow;
             final boolean shouldBeVisible = shouldBeVisibleH(row, isActive);
             Util.setVisOrGone(row.view, shouldBeVisible);
-            Util.setVisOrGone(row.header, shouldBeVisible);
+            Util.setVisOrGone(row.header, shouldBeVisible && mExpanded);
             if (row.view.isShown()) {
                 updateVolumeRowSliderTintH(row, isActive);
             }
@@ -699,6 +679,16 @@
         if (wasVisible != visible && !visible) {
             prepareForCollapse();
         }
+        if (visible != wasVisible) {
+            if (visible) {
+                HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter);
+            } else {
+                mHandler.postDelayed(() ->
+                        HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter),
+                        mExpandButtonAnimationDuration);
+            }
+
+        }
         Util.setVisOrGone(mZenFooter, visible);
         mZenFooter.update();
 
@@ -962,8 +952,7 @@
 
             @Override
             public void onTransitionEnd(Transition transition) {
-                mWindow.setLayout(
-                        mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
+                mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
             }
 
             @Override
@@ -972,8 +961,7 @@
 
             @Override
             public void onTransitionPause(Transition transition) {
-                mWindow.setLayout(
-                        mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
+                mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
             }
 
             @Override
@@ -1025,7 +1013,6 @@
                 initDialog();
                 mDensity = density;
             }
-            updateWindowWidthH();
             mConfigurableTexts.update();
             mZenFooter.onConfigurationChanged();
         }
@@ -1081,6 +1068,9 @@
             if (mExpandButtonAnimationRunning) return;
             final boolean newExpand = !mExpanded;
             Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
+            if (!newExpand) {
+                HardwareUiLayout.get(mDialogContentView).setCollapse();
+            }
             updateExpandedH(newExpand, false /* dismissing */);
         }
     };
@@ -1156,8 +1146,8 @@
             event.setPackageName(mContext.getPackageName());
 
             ViewGroup.LayoutParams params = getWindow().getAttributes();
-            boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) &&
-                    (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
+            boolean isFullScreen = (params.width == MATCH_PARENT) &&
+                    (params.height == MATCH_PARENT);
             event.setFullScreen(isFullScreen);
 
             if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index d6d0f75..8afd91d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.systemui.volume;
 
 import android.animation.Animator;
@@ -67,8 +66,8 @@
             @Override
             public void onShow(DialogInterface dialog) {
                 if (D.BUG) Log.d(TAG, "mDialog.onShow");
-                final int h = mDialogView.getHeight();
-                mDialogView.setTranslationY(-h);
+                final int w = mDialogView.getWidth() / 4;
+                mDialogView.setTranslationX(w);
                 startShowAnimation();
             }
         });
@@ -117,7 +116,7 @@
     }
 
     private int chevronDistance() {
-        return mChevron.getHeight() / 6;
+        return 0;
     }
 
     private int chevronPosY() {
@@ -128,7 +127,9 @@
     private void startShowAnimation() {
         if (D.BUG) Log.d(TAG, "startShowAnimation");
         mDialogView.animate()
+                .translationX(0)
                 .translationY(0)
+                .alpha(1)
                 .setDuration(scaledDuration(300))
                 .setInterpolator(new LogDecelerateInterpolator())
                 .setListener(null)
@@ -139,7 +140,6 @@
                         // reposition chevron
                         final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                         final int posY = chevronPosY();
-                        mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
                     }
                 })
                 .withEndAction(new Runnable() {
@@ -148,7 +148,6 @@
                         if (mChevronPositionAnimator == null) return;
                         // reposition chevron
                         final int posY = chevronPosY();
-                        mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
                     }
                 })
                 .start();
@@ -164,19 +163,13 @@
                 if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
                 setShowing(false);
             }
+
             @Override
             public void onAnimationCancel(Animator animation) {
                 if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
                 mCancelled = true;
             }
         });
-        mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float v = (Float) animation.getAnimatedValue();
-                mContents.setTranslationY(v + -mDialogView.getTranslationY());
-            }
-        });
         mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
         mContentsPositionAnimator.start();
 
@@ -218,34 +211,26 @@
             setShowing(false);
         }
         mDialogView.animate()
-                .translationY(-mDialogView.getHeight())
+                .translationX(mDialogView.getWidth() / 4)
+                .alpha(0)
                 .setDuration(scaledDuration(250))
                 .setInterpolator(new LogAccelerateInterpolator())
-                .setUpdateListener(new AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
-                        mContents.setTranslationY(-mDialogView.getTranslationY());
-                        final int posY = chevronPosY();
-                        mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
-                    }
-                })
                 .setListener(new AnimatorListenerAdapter() {
                     private boolean mCancelled;
+
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         if (mCancelled) return;
                         if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
-                        mHandler.postDelayed(new Runnable() {
-                            @Override
-                            public void run() {
-                                if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
-                                mDialog.dismiss();
-                                onComplete.run();
-                                setDismissing(false);
-                            }
+                        mHandler.postDelayed(() -> {
+                            if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
+                            mDialog.dismiss();
+                            onComplete.run();
+                            setDismissing(false);
                         }, PRE_DISMISS_DELAY);
 
                     }
+
                     @Override
                     public void onAnimationCancel(Animator animation) {
                         if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
@@ -258,13 +243,13 @@
         return (int) (base * ANIMATION_SCALE);
     }
 
-    private static final class LogDecelerateInterpolator implements TimeInterpolator {
+    public static final class LogDecelerateInterpolator implements TimeInterpolator {
         private final float mBase;
         private final float mDrift;
         private final float mTimeScale;
         private final float mOutputScale;
 
-        private LogDecelerateInterpolator() {
+        public LogDecelerateInterpolator() {
             this(400f, 1.4f, 0);
         }
 
@@ -286,12 +271,12 @@
         }
     }
 
-    private static final class LogAccelerateInterpolator implements TimeInterpolator {
+    public static final class LogAccelerateInterpolator implements TimeInterpolator {
         private final int mBase;
         private final int mDrift;
         private final float mLogScale;
 
-        private LogAccelerateInterpolator() {
+        public LogAccelerateInterpolator() {
             this(100, 0);
         }
 
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 8ac18e3..136aaad 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -38,6 +38,7 @@
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     SystemUIPluginLib \
+    android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
diff --git a/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
new file mode 100644
index 0000000..5b077be
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/RoundedCornersTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui;
+
+import static com.android.systemui.tuner.TunablePadding.FLAG_END;
+import static com.android.systemui.tuner.TunablePadding.FLAG_START;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.testing.AndroidTestingRunner;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.R.dimen;
+import com.android.systemui.RoundedCorners.TunablePaddingTagListener;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.tuner.TunablePadding;
+import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+public class RoundedCornersTest extends SysuiTestCase {
+
+    private RoundedCorners mRoundedCorners;
+    private StatusBar mStatusBar;
+    private WindowManager mWindowManager;
+    private FragmentService mFragmentService;
+    private FragmentHostManager mFragmentHostManager;
+    private TunerService mTunerService;
+    private StatusBarWindowView mView;
+    private TunablePaddingService mTunablePaddingService;
+
+    @Before
+    public void setup() {
+        mStatusBar = mock(StatusBar.class);
+        mWindowManager = mock(WindowManager.class);
+        mView = spy(new StatusBarWindowView(mContext, null));
+        when(mStatusBar.getStatusBarWindow()).thenReturn(mView);
+        mContext.putComponent(StatusBar.class, mStatusBar);
+
+        Display display = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
+        when(mWindowManager.getDefaultDisplay()).thenReturn(display);
+        mContext.addMockSystemService(WindowManager.class, mWindowManager);
+
+        mFragmentService = mDependency.injectMockDependency(FragmentService.class);
+        mFragmentHostManager = mock(FragmentHostManager.class);
+        when(mFragmentService.getFragmentHostManager(any())).thenReturn(mFragmentHostManager);
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+
+        mRoundedCorners = new RoundedCorners();
+        mRoundedCorners.mContext = mContext;
+        mRoundedCorners.mComponents = mContext.getComponents();
+
+        mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
+    }
+
+    @Test
+    public void testNoRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 0);
+
+        mRoundedCorners.start();
+        // No views added.
+        verify(mWindowManager, never()).addView(any(), any());
+        // No Fragments watched.
+        verify(mFragmentHostManager, never()).addTagListener(any(), any());
+        // No Tuners tuned.
+        verify(mTunerService, never()).addTunable(any(), any());
+    }
+
+    @Test
+    public void testRounding() {
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+
+        mRoundedCorners.start();
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+
+        // Add 3 tag listeners for each of the fragments that are needed.
+        verify(mFragmentHostManager, times(3)).addTagListener(any(), any());
+        // One tunable.
+        verify(mTunerService, times(1)).addTunable(any(), any());
+        // One TunablePadding.
+        verify(mTunablePaddingService, times(1)).add(any(), anyString(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testPaddingTagListener() {
+        TunablePaddingTagListener tagListener = new TunablePaddingTagListener(14, 5);
+        View v = mock(View.class);
+        View child = mock(View.class);
+        Fragment f = mock(Fragment.class);
+        TunablePadding padding = mock(TunablePadding.class);
+
+        when(mTunablePaddingService.add(any(), anyString(), anyInt(), anyInt()))
+                .thenReturn(padding);
+        when(f.getView()).thenReturn(v);
+        when(v.findViewById(5)).thenReturn(child);
+
+        // Trigger callback and verify we get a TunablePadding created.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(mTunablePaddingService).add(eq(child), eq(RoundedCorners.PADDING), eq(14),
+                eq(FLAG_START | FLAG_END));
+
+        // Call again and verify destroy is called.
+        tagListener.onFragmentViewCreated(null, f);
+        verify(padding).destroy();
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index b94a2fb..9d3124e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -31,6 +31,11 @@
         super(base, check);
     }
 
+    public ArrayMap<Class<?>, Object> getComponents() {
+        if (mComponents == null) mComponents = new ArrayMap<>();
+        return mComponents;
+    }
+
     @SuppressWarnings("unchecked")
     public <T> T getComponent(Class<T> interfaceType) {
         return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 2b14b31..0118a80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -210,6 +210,30 @@
     }
 
     @Test
+    public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, null);
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mContext.getString(R.string.notification_header_default_channel),
+                textView.getText());
+    }
+
+    @Test
+    public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null, null,
+                null, null);
+        final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(mDefaultNotificationChannel.getName(), textView.getText());
+    }
+
+    @Test
     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -325,6 +349,21 @@
     }
 
     @Test
+    public void testBindNotification_NumChannelsTextDisplaysWhenMoreThanOneChannelExists()
+            throws Exception {
+        when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                mNotificationChannel.getImportance(), mSbn, null, null,
+                null, null, null);
+        final TextView numChannelsView =
+                (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+        assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
+        assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
+    }
+
+    @Test
     public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -497,7 +536,7 @@
                 mNotificationChannel.getImportance(), mSbn, null, null, null,
                 null, null);
 
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), anyInt(), any());
     }
@@ -511,7 +550,7 @@
                 mNotificationChannel.getImportance(), mSbn, null, null, null,
                 null, null);
 
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), anyInt(), any());
     }
@@ -571,7 +610,7 @@
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
                 mNotificationChannel.getImportance(), mSbn, null, null, null,
                 null, Collections.singleton(TEST_PACKAGE_NAME));
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), anyInt(), any());
     }
@@ -586,7 +625,7 @@
 
         Switch enabledSwitch = mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         enabledSwitch.setChecked(false);
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
 
         ArgumentCaptor<NotificationChannel> updated =
                 ArgumentCaptor.forClass(NotificationChannel.class);
@@ -606,7 +645,7 @@
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         enabledSwitch.setChecked(false);
-        mNotificationInfo.handleCloseControls(false);
+        mNotificationInfo.handleCloseControls(false, false);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
     }
@@ -623,7 +662,7 @@
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         enabledSwitch.setChecked(false);
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
     }
@@ -641,7 +680,7 @@
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         enabledSwitch.setChecked(false);
-        mNotificationInfo.handleCloseControls(true);
+        mNotificationInfo.handleCloseControls(true, false);
         verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
index fbb25e5..15381b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.service.notification.StatusBarNotification;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.widget.RemoteViews;
@@ -41,7 +42,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
-import java.util.function.Function;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -67,7 +67,7 @@
         mNotificationInflater.setInflationCallback(new NotificationInflater.InflationCallback() {
             @Override
             public void handleInflationException(StatusBarNotification notification,
-                    InflationException e) {
+                    Exception e) {
             }
 
             @Override
@@ -77,6 +77,7 @@
     }
 
     @Test
+    @UiThreadTest
     public void testIncreasedHeadsUpBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
@@ -85,6 +86,7 @@
     }
 
     @Test
+    @UiThreadTest
     public void testIncreasedHeightBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
@@ -124,10 +126,10 @@
 
     @Test
     public void testAsyncTaskRemoved() throws Exception {
-        mRow.getEntry().abortInflation();
+        mRow.getEntry().abortTask();
         runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
                 mNotificationInflater);
-        Assert.assertTrue(mRow.getEntry().getRunningTasks().size() == 0);
+        Assert.assertNull(mRow.getEntry().getRunningTask() );
     }
 
     public static void runThenWaitForInflation(Runnable block,
@@ -143,7 +145,7 @@
         inflater.setInflationCallback(new NotificationInflater.InflationCallback() {
             @Override
             public void handleInflationException(StatusBarNotification notification,
-                    InflationException e) {
+                    Exception e) {
                 if (!expectingException) {
                     exceptionHolder.setException(e);
                 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index 87c4c66..ae0509a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -21,31 +21,76 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.doNothing;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.StringParceledListSlice;
 import android.net.ConnectivityManager;
+import android.security.IKeyChainService;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.systemui.statusbar.policy.SecurityController.SecurityControllerCallback;
 import com.android.systemui.SysuiTestCase;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class SecurityControllerTest extends SysuiTestCase {
+public class SecurityControllerTest extends SysuiTestCase implements SecurityControllerCallback {
     private final DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
+    private final IKeyChainService.Stub mKeyChainService = mock(IKeyChainService.Stub.class);
     private SecurityControllerImpl mSecurityController;
+    private CountDownLatch mStateChangedLatch;
+
+    // implementing SecurityControllerCallback
+    @Override
+    public void onStateChanged() {
+        mStateChangedLatch.countDown();
+    }
 
     @Before
     public void setUp() throws Exception {
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
         mContext.addMockSystemService(Context.CONNECTIVITY_SERVICE, mock(ConnectivityManager.class));
+
+        Intent intent = new Intent(IKeyChainService.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        mContext.addMockService(comp, mKeyChainService);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
+        // Without this line, mKeyChainService gets wrapped in a proxy when Stub.asInterface() is
+        // used on it, and the mocking above does not work.
+        when(mKeyChainService.queryLocalInterface("android.security.IKeyChainService"))
+                .thenReturn(mKeyChainService);
+
         mSecurityController = new SecurityControllerImpl(mContext);
+
+        // Wait for one or two state changes from the CACertLoader(s) in the constructor of
+        // mSecurityController
+        mStateChangedLatch = new CountDownLatch(mSecurityController.hasWorkProfile() ? 2 : 1);
+        mSecurityController.addCallback(this);
+    }
+
+    @After
+    public void tearDown() {
+        mSecurityController.removeCallback(this);
     }
 
     @Test
@@ -62,4 +107,41 @@
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn("organization");
         assertEquals("organization", mSecurityController.getDeviceOwnerOrganizationName());
     }
+
+    @Test
+    @Ignore("Flaky")
+    public void testCaCertLoader() throws Exception {
+        assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertFalse(mSecurityController.hasCACertInCurrentUser());
+
+        // With a CA cert
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenReturn(new StringParceledListSlice(Arrays.asList("One CA Alias")));
+
+        mSecurityController.new CACertLoader()
+                           .execute(0);
+
+        assertTrue(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInCurrentUser());
+
+        // Exception
+
+        mStateChangedLatch = new CountDownLatch(1);
+
+        when(mKeyChainService.getUserCaAliases())
+                .thenThrow(new AssertionError("Test AssertionError"))
+                .thenReturn(new StringParceledListSlice(new ArrayList<String>()));
+
+        mSecurityController.new CACertLoader()
+                           .execute(0);
+
+        assertFalse(mStateChangedLatch.await(3, TimeUnit.SECONDS));
+        assertTrue(mSecurityController.hasCACertInCurrentUser());
+        // The retry takes 30s
+        //assertTrue(mStateChangedLatch.await(31, TimeUnit.SECONDS));
+        //assertFalse(mSecurityController.hasCACertInCurrentUser());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
new file mode 100644
index 0000000..0b6d692
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.tuner;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.testing.LeakCheck.Tracker;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TunablePaddingTest extends LeakCheckedTest {
+
+    private static final String KEY = "KEY";
+    private static final int DEFAULT = 42;
+    private View mView;
+    private TunablePadding mTunablePadding;
+    private TunerService mTunerService;
+
+    @Before
+    public void setup() {
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mView = mock(View.class, withSettings().spiedInstance(new View(mContext)));
+
+        mTunerService = mDependency.injectMockDependency(TunerService.class);
+        Tracker tracker = mLeakCheck.getTracker("tuner");
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).addAllocation(new Throwable());
+            return null;
+        }).when(mTunerService).addTunable(any(), any());
+        doAnswer(invocation -> {
+            tracker.getLeakInfo(invocation.getArguments()[0]).clearAllocations();
+            return null;
+        }).when(mTunerService).removeTunable(any());
+    }
+
+    @Test
+    public void testFlags() {
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_TOP);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(DEFAULT), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_BOTTOM);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(0), eq(DEFAULT));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testRtl() {
+        when(mView.isLayoutRtl()).thenReturn(true);
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_END);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(DEFAULT), eq(0), eq(0), eq(0));
+        mTunablePadding.destroy();
+
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(null, null);
+        verify(mView).setPadding(eq(0), eq(0), eq(DEFAULT), eq(0));
+        mTunablePadding.destroy();
+    }
+
+    @Test
+    public void testTuning() {
+        int value = 3;
+        mTunablePadding = TunablePadding.addTunablePadding(mView, KEY, DEFAULT,
+                TunablePadding.FLAG_START);
+        mTunablePadding.onTuningChanged(KEY, String.valueOf(value));
+
+        DisplayMetrics metrics = new DisplayMetrics();
+        mContext.getSystemService(WindowManager.class).getDefaultDisplay().getMetrics(metrics);
+        int output = (int) (metrics.density * value);
+        verify(mView).setPadding(eq(output), eq(0), eq(0), eq(0));
+
+        mTunablePadding.destroy();
+    }
+}
\ No newline at end of file
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index ac544e8..8cecb4b 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -215,6 +215,10 @@
     // Package: com.android.systemui
     NOTE_LOGOUT_USER = 1011;
 
+    // Notify the user that a TV PIP is running.
+    // Package: com.android.systemui
+    NOTE_TV_PIP = 1100;
+
     // Communicate to the user about remote bugreports.
     // Package: android
     NOTE_REMOTE_BUGREPORT = 678432343;
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index 05ad161..238bf0f 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -2895,6 +2895,7 @@
             mAllocationArray[0] = createTyped(rs, t, usage);
             if ((usage & USAGE_IO_INPUT) != 0) {
                 if (numAlloc > MAX_NUMBER_IO_INPUT_ALLOC) {
+                    mAllocationArray[0].destroy();
                     throw new RSIllegalArgumentException("Exceeds the max number of Allocations allowed: " +
                                                          MAX_NUMBER_IO_INPUT_ALLOC);
                 }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index ac81565..b2712ff 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -373,11 +373,6 @@
     }
 
     private void onPackageBroadcastReceived(Intent intent, int userId) {
-        if (!mUserManager.isUserUnlockingOrUnlocked(userId) ||
-                isProfileWithLockedParent(userId)) {
-            return;
-        }
-
         final String action = intent.getAction();
         boolean added = false;
         boolean changed = false;
@@ -408,7 +403,11 @@
         }
 
         synchronized (mLock) {
-            ensureGroupStateLoadedLocked(userId);
+            if (!mUserManager.isUserUnlockingOrUnlocked(userId) ||
+                    isProfileWithLockedParent(userId)) {
+                return;
+            }
+            ensureGroupStateLoadedLocked(userId, /* enforceUserUnlockingOrUnlocked */ false);
 
             Bundle extras = intent.getExtras();
 
@@ -844,7 +843,7 @@
         mSecurityPolicy.enforceCallFromPackage(callingPackage);
 
         synchronized (mLock) {
-            ensureGroupStateLoadedLocked(userId);
+            ensureGroupStateLoadedLocked(userId, /* enforceUserUnlockingOrUnlocked */ false);
 
             // NOTE: The lookup is enforcing security across users by making
             // sure the caller can only access hosts it owns.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index b536ad9..4dd0b35 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -118,7 +118,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
-                mUi.hideAll();
+                mUi.hideAll(null);
             }
         }
     };
@@ -213,7 +213,7 @@
                             if (!doit) {
                                 return true;
                             }
-                            handleActiveAutofillServiceRemoved(getChangingUserId());
+                            removeCachedServiceLocked(getChangingUserId());
                         }
                     }
                 }
@@ -454,10 +454,12 @@
         }
 
         @Override
-        public void setAuthenticationResult(Bundle data, int sessionId, int userId) {
+        public void setAuthenticationResult(Bundle data, int sessionId, int authenticationId,
+                int userId) {
             synchronized (mLock) {
                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
-                service.setAuthenticationResultLocked(data, sessionId, getCallingUid());
+                service.setAuthenticationResultLocked(data, sessionId, authenticationId,
+                        getCallingUid());
             }
         }
 
@@ -470,9 +472,9 @@
         }
 
         @Override
-        public int startSession(IBinder activityToken, IBinder windowToken, IBinder appCallback,
-                AutofillId autofillId, Rect bounds, AutofillValue value, int userId,
-                boolean hasCallback, int flags, String packageName) {
+        public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
+                Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags,
+                String packageName) {
 
             activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
             appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
@@ -489,8 +491,8 @@
 
             synchronized (mLock) {
                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
-                return service.startSessionLocked(activityToken, getCallingUid(), windowToken,
-                        appCallback, autofillId, bounds, value, hasCallback, flags, packageName);
+                return service.startSessionLocked(activityToken, getCallingUid(), appCallback,
+                        autofillId, bounds, value, hasCallback, flags, packageName);
             }
         }
 
@@ -528,19 +530,6 @@
         }
 
         @Override
-        public void setWindow(int sessionId, IBinder windowToken) throws RemoteException {
-            windowToken = Preconditions.checkNotNull(windowToken, "windowToken");
-
-            synchronized (mLock) {
-                final AutofillManagerServiceImpl service = mServicesCache.get(
-                        UserHandle.getCallingUserId());
-                if (service != null) {
-                    service.setWindow(sessionId, getCallingUid(), windowToken);
-                }
-            }
-        }
-
-        @Override
         public void updateSession(int sessionId, AutofillId id, Rect bounds,
                 AutofillValue value, int action, int flags, int userId) {
             synchronized (mLock) {
@@ -602,6 +591,31 @@
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
+            boolean showHistory = true;
+            boolean uiOnly = false;
+            if (args != null) {
+                for (String arg : args) {
+                    switch(arg) {
+                        case "--no-history":
+                            showHistory = false;
+                            break;
+                        case "--ui-only":
+                            uiOnly = true;
+                            break;
+                        case "--help":
+                            pw.println("Usage: dumpsys autofill [--ui-only|--no-history]");
+                            return;
+                        default:
+                            throw new IllegalArgumentException("Invalid dump arg: " + arg);
+                    }
+                }
+            }
+
+            if (uiOnly) {
+                mUi.dump(pw);
+                return;
+            }
+
             boolean oldDebug = sDebug;
             try {
                 synchronized (mLock) {
@@ -624,8 +638,10 @@
                     }
                     mUi.dump(pw);
                 }
-                pw.println("Requests history:");
-                mRequestsHistory.reverseDump(fd, pw, args);
+                if (showHistory) {
+                    pw.println("Requests history:");
+                    mRequestsHistory.reverseDump(fd, pw, args);
+                }
             } finally {
                 setDebugLocked(oldDebug);
             }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 4507eae..faa6182 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -19,17 +19,21 @@
 import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
 import static android.view.autofill.AutofillManager.NO_SESSION;
 
+import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.AppGlobals;
+import android.app.IActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.Rect;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -46,6 +50,7 @@
 import android.service.autofill.FillResponse;
 import android.service.autofill.IAutoFillService;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.LocalLog;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -72,6 +77,9 @@
     private static final String TAG = "AutofillManagerServiceImpl";
     private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
 
+    /** Minimum interval to prune abandoned sessions */
+    private static final int MAX_ABANDONED_SESSION_MILLIS = 30000;
+
     static final int MSG_SERVICE_SAVE = 1;
 
     private final int mUserId;
@@ -104,10 +112,10 @@
             mHandlerCallback, true);
 
     /**
-     * Cache of pending {@link Session}s, keyed by {@code activityToken}.
+     * Cache of pending {@link Session}s, keyed by sessionId.
      *
      * <p>They're kept until the {@link AutofillService} finished handling a request, an error
-     * occurs, or the session times out.
+     * occurs, or the session is abandoned.
      */
     @GuardedBy("mLock")
     private final SparseArray<Session> mSessions = new SparseArray<>();
@@ -116,6 +124,9 @@
     @GuardedBy("mLock")
     private FillEventHistory mEventHistory;
 
+    /** When was {@link PruneTask} last executed? */
+    private long mLastPrune = 0;
+
     AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
             int userId, AutoFillUI ui, boolean disabled) {
         mContext = context;
@@ -230,13 +241,13 @@
         return isEnabled();
     }
 
-    void setAuthenticationResultLocked(Bundle data, int sessionId, int uid) {
+    void setAuthenticationResultLocked(Bundle data, int sessionId, int authenticationId, int uid) {
         if (!isEnabled()) {
             return;
         }
         final Session session = mSessions.get(sessionId);
         if (session != null && uid == session.uid) {
-            session.setAuthenticationResultLocked(data);
+            session.setAuthenticationResultLocked(data, authenticationId);
         }
     }
 
@@ -252,7 +263,7 @@
         }
     }
 
-    int startSessionLocked(@NonNull IBinder activityToken, int uid, @Nullable IBinder windowToken,
+    int startSessionLocked(@NonNull IBinder activityToken, int uid,
             @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
             @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
             int flags, @NonNull String packageName) {
@@ -260,8 +271,11 @@
             return 0;
         }
 
-        final Session newSession = createSessionByTokenLocked(activityToken, uid, windowToken,
-                appCallbackToken, hasCallback, flags, packageName);
+        // Occasionally clean up abandoned sessions
+        pruneAbandonedSessionsLocked();
+
+        final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
+                hasCallback, flags, packageName);
         if (newSession == null) {
             return NO_SESSION;
         }
@@ -277,6 +291,20 @@
         return newSession.id;
     }
 
+    /**
+     * Remove abandoned sessions if needed.
+     */
+    private void pruneAbandonedSessionsLocked() {
+        long now = System.currentTimeMillis();
+        if (mLastPrune < now - MAX_ABANDONED_SESSION_MILLIS) {
+            mLastPrune = now;
+
+            if (mSessions.size() > 0) {
+                (new PruneTask()).execute();
+            }
+        }
+    }
+
     void finishSessionLocked(int sessionId, int uid) {
         if (!isEnabled()) {
             return;
@@ -331,8 +359,8 @@
     }
 
     private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
-            @Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
-            int flags, @NonNull String packageName) {
+            @NonNull IBinder appCallbackToken, boolean hasCallback, int flags,
+            @NonNull String packageName) {
         // use random ids so that one app cannot know that another app creates sessions
         int sessionId;
         int tries = 0;
@@ -347,7 +375,7 @@
         } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
 
         final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
-                sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback,
+                sessionId, uid, activityToken, appCallbackToken, hasCallback,
                 mInfo.getServiceInfo().getComponentName(), packageName);
         mSessions.put(newSession.id, newSession);
 
@@ -374,24 +402,6 @@
         }
     }
 
-    /**
-     * Set the window the UI should get attached to
-     *
-     * @param sessionId The id of the session to restore
-     * @param uid UID of the process that tries to restore the session
-     * @param windowToken The window the activity is now in
-     */
-    boolean setWindow(int sessionId, int uid, @NonNull IBinder windowToken) {
-        final Session session = mSessions.get(sessionId);
-
-        if (session == null || uid != session.uid) {
-            return false;
-        } else {
-            session.switchWindow(windowToken);
-            return true;
-        }
-    }
-
     void updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
             AutofillValue value, int action, int flags) {
         final Session session = mSessions.get(sessionId);
@@ -513,6 +523,7 @@
         pw.print(prefix); pw.print("Default component: ");
             pw.println(mContext.getString(R.string.config_defaultAutofillService));
         pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
+        pw.print(prefix); pw.print("Last prune: "); pw.println(mLastPrune);
 
         final int size = mSessions.size();
         if (size == 0) {
@@ -604,4 +615,62 @@
                 + ", component=" + (mInfo != null
                 ? mInfo.getServiceInfo().getComponentName() : null) + "]";
     }
+
+    /** Task used to prune abandoned session */
+    private class PruneTask extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... ignored) {
+            int numSessionsToRemove;
+            ArrayMap<IBinder, Integer> sessionsToRemove;
+
+            synchronized (mLock) {
+                numSessionsToRemove = mSessions.size();
+                sessionsToRemove = new ArrayMap<>(numSessionsToRemove);
+
+                for (int i = 0; i < numSessionsToRemove; i++) {
+                    Session session = mSessions.valueAt(i);
+
+                    sessionsToRemove.put(session.getActivityTokenLocked(), session.id);
+                }
+            }
+
+            IActivityManager am = ActivityManager.getService();
+
+            // Only remove sessions which's activities are not known to the activity manager anymore
+            for (int i = 0; i < numSessionsToRemove; i++) {
+                try {
+                    // The activity manager cannot resolve activities that have been removed
+                    if (am.getActivityClassForToken(sessionsToRemove.keyAt(i)) != null) {
+                        sessionsToRemove.removeAt(i);
+                        i--;
+                        numSessionsToRemove--;
+                    }
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Cannot figure out if activity is finished", e);
+                }
+            }
+
+            synchronized (mLock) {
+                for (int i = 0; i < numSessionsToRemove; i++) {
+                    Session sessionToRemove = mSessions.get(sessionsToRemove.valueAt(i));
+
+                    if (sessionToRemove != null) {
+                        if (sessionToRemove.isSavingLocked()) {
+                            if (sVerbose) {
+                                Slog.v(TAG, "Session " + sessionToRemove.id + " is saving");
+                            }
+                        } else {
+                            if (sDebug) {
+                                Slog.i(TAG, "Prune session " + sessionToRemove.id + " ("
+                                    + sessionToRemove.getActivityTokenLocked() + ")");
+                            }
+                            sessionToRemove.removeSelfLocked();
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index cbf97dd..8d947b9 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -20,9 +20,7 @@
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.os.Bundle;
-import android.util.DebugUtils;
 import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -68,10 +66,6 @@
         return builder.toString();
     }
 
-    static String getUpdateActionAsString(int action) {
-        return DebugUtils.flagsToString(AutofillManager.class, "ACTION_", action);
-    }
-
     static ViewNode findViewNodeById(@NonNull AssistStructure structure, @NonNull AutofillId id) {
         final int size = structure.getWindowNodeCount();
         for (int i = 0; i < size; i++) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 23b734a..70771e8 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -26,11 +26,9 @@
 import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
 
 import static com.android.server.autofill.Helper.findViewNodeById;
-import static com.android.server.autofill.Helper.getUpdateActionAsString;
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 import static com.android.server.autofill.ViewState.STATE_AUTOFILLED;
-import static com.android.server.autofill.ViewState.STATE_FILLABLE;
 import static com.android.server.autofill.ViewState.STATE_RESTARTED_SESSION;
 
 import android.annotation.NonNull;
@@ -59,7 +57,6 @@
 import android.service.autofill.SaveInfo;
 import android.service.autofill.SaveRequest;
 import android.util.ArrayMap;
-import android.util.DebugUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.autofill.AutofillId;
@@ -80,6 +77,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -120,9 +118,6 @@
     @GuardedBy("mLock")
     @NonNull private IBinder mActivityToken;
 
-    @GuardedBy("mLock")
-    @NonNull private IBinder mWindowToken;
-
     /** Package name of the app that is auto-filled */
     @NonNull private final String mPackageName;
 
@@ -144,18 +139,6 @@
     private SparseArray<FillResponse> mResponses;
 
     /**
-     * Response that requires a service authentitcation request.
-     */
-    @GuardedBy("mLock")
-    private FillResponse mResponseWaitingAuth;
-
-    /**
-     * Dataset that when tapped launched a service authentication request.
-     */
-    @GuardedBy("mLock")
-    private Dataset mDatasetWaitingAuth;
-
-    /**
      * Contexts read from the app; they will be updated (sanitized, change values for save) before
      * sent to {@link AutofillService}. Ordered by the time they we read.
      */
@@ -177,6 +160,10 @@
     @GuardedBy("mLock")
     private boolean mDestroyed;
 
+    /** Whether the session is currently saving */
+    @GuardedBy("mLock")
+    private boolean mIsSaving;
+
     /**
      * Receiver of assist data from the app's {@link Activity}.
      */
@@ -338,7 +325,7 @@
     Session(@NonNull AutofillManagerServiceImpl service, @NonNull AutoFillUI ui,
             @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
             @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
-            @Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
+            @NonNull IBinder client, boolean hasCallback,
             @NonNull ComponentName componentName, @NonNull String packageName) {
         id = sessionId;
         this.uid = uid;
@@ -348,7 +335,6 @@
         mHandlerCaller = handlerCaller;
         mRemoteFillService = new RemoteFillService(context, componentName, userId, this);
         mActivityToken = activityToken;
-        mWindowToken = windowToken;
         mHasCallback = hasCallback;
         mPackageName = packageName;
         mClient = IAutoFillManagerClient.Stub.asInterface(client);
@@ -361,28 +347,11 @@
      *
      * @return The activity token
      */
-    IBinder getActivityTokenLocked() {
+    @NonNull IBinder getActivityTokenLocked() {
         return mActivityToken;
     }
 
     /**
-     * Sets new window  for this session.
-     *
-     * @param newWindow The window the Ui should be attached to. Can be {@code null} if no
-     *                  further UI is needed.
-     */
-    void switchWindow(@NonNull IBinder newWindow) {
-        synchronized (mLock) {
-            if (mDestroyed) {
-                Slog.w(TAG, "Call to Session#switchWindow() rejected - session: "
-                        + id + " destroyed");
-                return;
-            }
-            mWindowToken = newWindow;
-        }
-    }
-
-    /**
      * Sets new activity and client for this session.
      *
      * @param newActivity The token of the new activity
@@ -416,7 +385,7 @@
         }
         if (response == null) {
             if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
-                getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
+                getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
             }
             // Nothing to be done, but need to notify client.
             notifyUnavailableToClient();
@@ -432,10 +401,6 @@
             notifyUnavailableToClient();
         }
         synchronized (mLock) {
-            if (response.getAuthentication() != null) {
-                // TODO(b/37424539): proper implementation
-                mResponseWaitingAuth = response;
-            }
             processResponseLocked(response);
         }
 
@@ -466,7 +431,7 @@
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
         mMetricsLogger.write(log);
 
-        getUiForShowing().showError(message);
+        getUiForShowing().showError(message, this);
         removeSelf();
     }
 
@@ -474,6 +439,8 @@
     @Override
     public void onSaveRequestSuccess(@NonNull String servicePackageName) {
         synchronized (mLock) {
+            mIsSaving = false;
+
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onSaveRequestSuccess() rejected - session: "
                         + id + " destroyed");
@@ -496,6 +463,8 @@
     public void onSaveRequestFailure(@Nullable CharSequence message,
             @NonNull String servicePackageName) {
         synchronized (mLock) {
+            mIsSaving = false;
+
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#onSaveRequestFailure() rejected - session: "
                         + id + " destroyed");
@@ -509,7 +478,7 @@
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
         mMetricsLogger.write(log);
 
-        getUiForShowing().showError(message);
+        getUiForShowing().showError(message, this);
         removeSelf();
     }
 
@@ -539,7 +508,7 @@
 
     // FillServiceCallbacks
     @Override
-    public void authenticate(int requestId, IntentSender intent, Bundle extras) {
+    public void authenticate(int requestId, int datasetIndex, IntentSender intent, Bundle extras) {
         final Intent fillInIntent;
         synchronized (mLock) {
             synchronized (mLock) {
@@ -555,7 +524,9 @@
 
         mService.setAuthenticationSelected();
 
-        mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
+        final int authenticationId = AutofillManager.makeAuthenticationId(requestId, datasetIndex);
+        mHandlerCaller.getHandler().post(() -> startAuthentication(authenticationId,
+                intent, fillInIntent));
     }
 
     // FillServiceCallbacks
@@ -566,7 +537,7 @@
 
     // AutoFillUiCallback
     @Override
-    public void fill(int requestId, Dataset dataset) {
+    public void fill(int requestId, int datasetIndex, Dataset dataset) {
         synchronized (mLock) {
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#fill() rejected - session: "
@@ -574,7 +545,7 @@
                 return;
             }
         }
-        mHandlerCaller.getHandler().post(() -> autoFill(requestId, dataset));
+        mHandlerCaller.getHandler().post(() -> autoFill(requestId, datasetIndex, dataset));
     }
 
     // AutoFillUiCallback
@@ -596,6 +567,8 @@
     @Override
     public void cancelSave() {
         synchronized (mLock) {
+            mIsSaving = false;
+
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
                         + id + " destroyed");
@@ -618,8 +591,8 @@
             if (id.equals(mCurrentViewId)) {
                 try {
                     final ViewState view = mViewStates.get(id);
-                    mClient.requestShowFillUi(this.id, mWindowToken, id, width, height,
-                            view.getVirtualBounds(), presenter);
+                    mClient.requestShowFillUi(this.id, id, width, height, view.getVirtualBounds(),
+                            presenter);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Error requesting to show fill UI", e);
                 }
@@ -639,7 +612,7 @@
             // NOTE: We allow this call in a destroyed state as the UI is
             // asked to go away after we get destroyed, so let it do that.
             try {
-                mClient.requestHideFillUi(this.id, mWindowToken, id);
+                mClient.requestHideFillUi(this.id, id);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error requesting to hide fill UI", e);
             }
@@ -668,42 +641,42 @@
         });
     }
 
-    void setAuthenticationResultLocked(Bundle data) {
+    void setAuthenticationResultLocked(Bundle data, int authenticationId) {
         if (mDestroyed) {
             Slog.w(TAG, "Call to Session#setAuthenticationResultLocked() rejected - session: "
                     + id + " destroyed");
             return;
         }
-        if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
-            removeSelf();
-        } else {
-            final Parcelable result = data.getParcelable(
-                    AutofillManager.EXTRA_AUTHENTICATION_RESULT);
-            if (result instanceof FillResponse) {
-                FillResponse response = (FillResponse) result;
 
-                mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
-                final int requestIndex = mResponses.indexOfValue(mResponseWaitingAuth);
-                mResponseWaitingAuth = null;
-                if (requestIndex >= 0) {
-                    response.setRequestId(mResponses.keyAt(requestIndex));
-                    processResponseLocked(response);
-                } else {
-                    Slog.e(TAG, "Error cannot find id for auth response");
-                }
-            } else if (result instanceof Dataset) {
+        final int requestId = AutofillManager.getRequestIdFromAuthenticationId(authenticationId);
+        final FillResponse authenticatedResponse = mResponses.get(requestId);
+        if (authenticatedResponse == null || data == null) {
+            removeSelf();
+            return;
+        }
+
+        final int datasetIdx = AutofillManager.getDatasetIdFromAuthenticationId(
+                authenticationId);
+        // Authenticated a dataset - reset view state regardless if we got a response or a dataset
+        if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
+            final Dataset dataset = authenticatedResponse.getDatasets().get(datasetIdx);
+            if (dataset == null) {
+                removeSelf();
+                return;
+            }
+            resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
+        }
+
+        final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+        if (result instanceof FillResponse) {
+            final FillResponse response = (FillResponse) result;
+            mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
+            replaceResponseLocked(authenticatedResponse, response);
+        } else if (result instanceof Dataset) {
+            if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
                 final Dataset dataset = (Dataset) result;
-                for (int i = 0; i < mResponses.size(); i++) {
-                    final FillResponse response = mResponses.valueAt(i);
-                    final int index = response.getDatasets().indexOf(mDatasetWaitingAuth);
-                    if (index >= 0) {
-                        response.getDatasets().set(index, dataset);
-                        mDatasetWaitingAuth = null;
-                        autoFill(mResponses.keyAt(i), dataset);
-                        resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
-                        return;
-                    }
-                }
+                authenticatedResponse.getDatasets().set(datasetIdx, dataset);
+                autoFill(requestId, datasetIdx, dataset);
             }
         }
     }
@@ -830,7 +803,10 @@
             }
             if (atLeastOneChanged) {
                 mService.setSaveShown();
-                getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName);
+                getUiForShowing().showSaveUi(mService.getServiceLabel(), saveInfo, mPackageName,
+                        this);
+
+                mIsSaving = true;
                 return false;
             }
         }
@@ -844,6 +820,13 @@
     }
 
     /**
+     * Returns whether the session is currently showing the save UI
+     */
+    boolean isSavingLocked() {
+        return mIsSaving;
+    }
+
+    /**
      * Calls service when user requested save.
      */
     void callSaveLocked() {
@@ -929,6 +912,7 @@
         }
     }
 
+    private static final int PARTITION_MAX_COUNT = 64;
     /**
      * Determines if a new partition should be started for an id.
      *
@@ -942,6 +926,11 @@
         }
 
         final int numResponses = mResponses.size();
+        if (numResponses >= PARTITION_MAX_COUNT) {
+            Slog.e(TAG, "Cannot create more than 64 partitions. Not creating a new partition.");
+            return false;
+        }
+
         for (int responseNum = 0; responseNum < numResponses; responseNum++) {
             final FillResponse response = mResponses.valueAt(responseNum);
 
@@ -986,18 +975,14 @@
             return;
         }
         if (sVerbose) {
-            Slog.v(TAG, "updateLocked(): id=" + id + ", action=" + getUpdateActionAsString(action)
-                    + ", flags=" + flags);
+            Slog.v(TAG, "updateLocked(): id=" + id + ", action=" + action + ", flags=" + flags);
         }
         ViewState viewState = mViewStates.get(id);
 
         if (viewState == null) {
             if (action == ACTION_START_SESSION || action == ACTION_VALUE_CHANGED
                     || action == ACTION_VIEW_ENTERED) {
-                if (sVerbose) {
-                    Slog.v(TAG,
-                            "Creating viewState for " + id + " on " + getActionAsString(action));
-                }
+                if (sVerbose) Slog.v(TAG, "Creating viewState for " + id + " on " + action);
                 boolean isIgnored = isIgnoredLocked(id);
                 viewState = new ViewState(this, id, value, this,
                         isIgnored ? ViewState.STATE_IGNORED : ViewState.STATE_INITIAL);
@@ -1007,7 +992,7 @@
                     return;
                 }
             } else {
-                if (sVerbose) Slog.v(TAG, "Ignored " + getActionAsString(action) + " for " + id);
+                if (sVerbose) Slog.v(TAG, "Ignored action " + action + " for " + id);
                 return;
             }
         }
@@ -1036,18 +1021,21 @@
 
                     //..and the UI
                     if (value.isText()) {
-                        getUiForShowing().filterFillUi(value.getTextValue().toString());
+                        getUiForShowing().filterFillUi(value.getTextValue().toString(), this);
                     } else {
-                        getUiForShowing().filterFillUi(null);
+                        getUiForShowing().filterFillUi(null, this);
                     }
                 }
                 break;
             case ACTION_VIEW_ENTERED:
+                if (sVerbose && virtualBounds != null) {
+                    Slog.w(TAG, "entered on virtual child " + id + ": " + virtualBounds);
+                }
                 requestNewFillResponseIfNecessaryLocked(id, viewState, flags);
 
                 // Remove the UI if the ViewState has changed.
                 if (mCurrentViewId != viewState.id) {
-                    mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
+                    hideFillUiIfOwnedByMe();
                     mCurrentViewId = viewState.id;
                 }
 
@@ -1056,7 +1044,8 @@
                 break;
             case ACTION_VIEW_EXITED:
                 if (mCurrentViewId == viewState.id) {
-                    mUi.hideFillUi(viewState.id);
+                    if (sVerbose) Slog.d(TAG, "Exiting view " + id);
+                    hideFillUiIfOwnedByMe();
                     mCurrentViewId = null;
                 }
                 break;
@@ -1093,11 +1082,7 @@
             filterText = value.getTextValue().toString();
         }
 
-        getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
-    }
-
-    String getActionAsString(int flag) {
-        return DebugUtils.flagsToString(AutofillManager.class, "ACTION_", flag);
+        getUiForShowing().showFillUi(filledId, response, filterText, mPackageName, this);
     }
 
     boolean isDestroyed() {
@@ -1116,10 +1101,9 @@
         synchronized (mLock) {
             if (!mHasCallback) return;
             try {
-                mClient.notifyNoFillUi(id, mWindowToken, mCurrentViewId);
+                mClient.notifyNoFillUi(id, mCurrentViewId);
             } catch (RemoteException e) {
-                Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
-                        + " id=" + mCurrentViewId, e);
+                Slog.e(TAG, "Error notifying client no fill UI: id=" + mCurrentViewId, e);
             }
         }
     }
@@ -1157,26 +1141,43 @@
         }
     }
 
-    private void processResponseLocked(@NonNull FillResponse response) {
+    private void replaceResponseLocked(@NonNull FillResponse oldResponse,
+            @NonNull FillResponse newResponse) {
+        // Disassociate view states with the old response
+        setViewStatesLocked(oldResponse, ViewState.STATE_INITIAL, true);
+        // Move over the id
+        newResponse.setRequestId(oldResponse.getRequestId());
+        // Replace the old response
+        mResponses.put(newResponse.getRequestId(), newResponse);
+        // Now process the new response
+        processResponseLocked(newResponse);
+    }
+
+    private void processResponseLocked(@NonNull FillResponse newResponse) {
+        // Make sure we are hiding the UI which will be shown
+        // only if handling the current response requires it.
+        hideAllUiIfOwnedByMe();
+
+        final int requestId = newResponse.getRequestId();
         if (sVerbose) {
-            Slog.v(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
+            Slog.v(TAG, "processResponseLocked(): mCurrentViewId=" + mCurrentViewId
+                    + ", reqId=" + requestId + ", resp=" + newResponse);
         }
 
         if (mResponses == null) {
             mResponses = new SparseArray<>(4);
         }
-        final int requestId = response.getRequestId();
-        mResponses.put(requestId, response);
-        mClientState = response.getClientState();
+        mResponses.put(requestId, newResponse);
+        mClientState = newResponse.getClientState();
 
-        setViewStatesLocked(response, ViewState.STATE_FILLABLE);
+        setViewStatesLocked(newResponse, ViewState.STATE_FILLABLE, false);
         updateTrackedIdsLocked();
 
         if (mCurrentViewId == null) {
             return;
         }
 
-        final ArrayList<Dataset> datasets = response.getDatasets();
+        final ArrayList<Dataset> datasets = newResponse.getDatasets();
 
         if (datasets != null && datasets.size() == 1) {
             // Check if it its a single response for a manual request, in which case it should
@@ -1184,7 +1185,7 @@
             final FillContext context = getFillContextByRequestIdLocked(requestId);
             if (context != null && (context.getStructure().getFlags() & FLAG_MANUAL_REQUEST) != 0) {
                 Slog.d(TAG, "autofilling manual request directly");
-                autoFill(requestId, datasets.get(0));
+                autoFill(requestId, 0, datasets.get(0));
                 return;
             }
         }
@@ -1196,7 +1197,7 @@
     /**
      * Sets the state of all views in the given response.
      */
-    private void setViewStatesLocked(FillResponse response, int state) {
+    private void setViewStatesLocked(FillResponse response, int state, boolean clearResponse) {
         final ArrayList<Dataset> datasets = response.getDatasets();
         if (datasets != null) {
             for (int i = 0; i < datasets.size(); i++) {
@@ -1205,7 +1206,16 @@
                     Slog.w(TAG, "Ignoring null dataset on " + datasets);
                     continue;
                 }
-                setViewStatesLocked(response, dataset, state);
+                setViewStatesLocked(response, dataset, state, clearResponse);
+            }
+        } else if (response.getAuthentication() != null) {
+            for (AutofillId autofillId : response.getAuthenticationIds()) {
+                final ViewState viewState = createOrUpdateViewStateLocked(autofillId, state, null);
+                if (!clearResponse) {
+                    viewState.setResponse(response);
+                } else {
+                    viewState.setResponse(null);
+                }
             }
         }
         final SaveInfo saveInfo = response.getSaveInfo();
@@ -1228,14 +1238,13 @@
                 createOrUpdateViewStateLocked(id, state, null);
             }
         }
-
     }
 
     /**
      * Sets the state of all views in the given dataset and response.
      */
     private void setViewStatesLocked(@Nullable FillResponse response, @NonNull Dataset dataset,
-            int state) {
+            int state, boolean clearResponse) {
         final ArrayList<AutofillId> ids = dataset.getFieldIds();
         final ArrayList<AutofillValue> values = dataset.getFieldValues();
         for (int j = 0; j < ids.size(); j++) {
@@ -1244,11 +1253,14 @@
             final ViewState viewState = createOrUpdateViewStateLocked(id, state, value);
             if (response != null) {
                 viewState.setResponse(response);
+            } else if (clearResponse) {
+                viewState.setResponse(null);
             }
         }
     }
 
-    private ViewState createOrUpdateViewStateLocked(AutofillId id, int state, AutofillValue value) {
+    private ViewState createOrUpdateViewStateLocked(@NonNull AutofillId id, int state,
+            @Nullable AutofillValue value) {
         ViewState viewState = mViewStates.get(id);
         if (viewState != null)  {
             viewState.setState(state);
@@ -1279,7 +1291,7 @@
         }
     }
 
-    void autoFill(int requestId, Dataset dataset) {
+    void autoFill(int requestId, int datasetIndex, Dataset dataset) {
         synchronized (mLock) {
             if (mDestroyed) {
                 Slog.w(TAG, "Call to Session#autoFill() rejected - session: "
@@ -1297,11 +1309,13 @@
             // ...or handle authentication.
             // TODO(b/37424539): proper implementation
             mService.setDatasetAuthenticationSelected(dataset.getId());
-            mDatasetWaitingAuth = dataset;
-            setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
+            setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH, false);
             final Intent fillInIntent = createAuthFillInIntent(
-                    getFillContextByRequestIdLocked(requestId).getStructure(), null);
-            startAuthentication(dataset.getAuthentication(), fillInIntent);
+                    getFillContextByRequestIdLocked(requestId).getStructure(), mClientState);
+
+            final int authenticationId = AutofillManager.makeAuthenticationId(requestId,
+                    datasetIndex);
+            startAuthentication(authenticationId, dataset.getAuthentication(), fillInIntent);
         }
     }
 
@@ -1311,25 +1325,18 @@
         }
     }
 
-    FillResponse getResponseWaitingAuth() {
-        synchronized (mLock) {
-            return mResponseWaitingAuth;
-        }
-    }
-
     private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
         final Intent fillInIntent = new Intent();
         fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
-        if (extras != null) {
-            fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE, extras);
-        }
+        fillInIntent.putExtra(AutofillManager.EXTRA_CLIENT_STATE, extras);
         return fillInIntent;
     }
 
-    private void startAuthentication(IntentSender intent, Intent fillInIntent) {
+    private void startAuthentication(int authenticationId, IntentSender intent,
+            Intent fillInIntent) {
         try {
             synchronized (mLock) {
-                mClient.authenticate(id, intent, fillInIntent);
+                mClient.authenticate(id, authenticationId, intent, fillInIntent);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "Error launching auth intent", e);
@@ -1341,11 +1348,10 @@
         pw.print(prefix); pw.print("uid: "); pw.println(uid);
         pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
         pw.print(prefix); pw.print("mResponses: "); pw.println(mResponses);
-        pw.print(prefix); pw.print("mResponseWaitingAuth: "); pw.println(mResponseWaitingAuth);
-        pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
         pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
         pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
         pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
+        pw.print(prefix); pw.print("mIsSaving: "); pw.println(mIsSaving);
         final String prefix2 = prefix + "  ";
         for (Map.Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
             pw.print(prefix); pw.print("State for id "); pw.println(entry.getKey());
@@ -1385,9 +1391,21 @@
             }
             try {
                 if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
-                mClient.autofill(id, mWindowToken, dataset.getFieldIds(),
-                        dataset.getFieldValues());
-                setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED);
+                // Skip null values as a null values means no change
+                final int entryCount = dataset.getFieldIds().size();
+                final List<AutofillId> ids = new ArrayList<>(entryCount);
+                final List<AutofillValue> values = new ArrayList<>(entryCount);
+                for (int i = 0; i < entryCount; i++) {
+                    if (dataset.getFieldValues().get(i) == null) {
+                        continue;
+                    }
+                    ids.add(dataset.getFieldIds().get(i));
+                    values.add(dataset.getFieldValues().get(i));
+                }
+                if (!ids.isEmpty()) {
+                    mClient.autofill(id, ids, values);
+                }
+                setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED, false);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Error autofilling activity: " + e);
             }
@@ -1406,12 +1424,20 @@
             return;
         }
         mRemoteFillService.destroy();
-        mUi.hideAll();
-        mUi.setCallback(null);
+        hideAllUiIfOwnedByMe();
+        mUi.clearCallback(this);
         mDestroyed = true;
         mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
     }
 
+    private void hideAllUiIfOwnedByMe() {
+        mUi.hideAll(this);
+    }
+
+    private void hideFillUiIfOwnedByMe() {
+        mUi.hideFillUi(this);
+    }
+
     private void removeSelf() {
         synchronized (mLock) {
             removeSelfLocked();
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 561c603..f87fa19 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -112,7 +112,7 @@
         return mAutofilledValue;
     }
 
-    void setAutofilledValue(AutofillValue value) {
+    void setAutofilledValue(@Nullable AutofillValue value) {
         mAutofilledValue = value;
     }
 
@@ -180,15 +180,9 @@
         }
         // First try the current response associated with this View.
         if (mResponse != null) {
-            if (mResponse.getDatasets() != null) {
+            if (mResponse.getDatasets() != null || mResponse.getAuthentication() != null) {
                 mListener.onFillReady(mResponse, this.id, mCurrentValue);
             }
-            return;
-        }
-        // Then checks if the session has a response waiting authentication; if so, uses it instead.
-        final FillResponse responseWaitingAuth = mSession.getResponseWaitingAuth();
-        if (responseWaitingAuth != null) {
-            mListener.onFillReady(responseWaitingAuth, this.id, mCurrentValue);
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 086742e..4f69f64 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -30,6 +30,7 @@
 import android.text.TextUtils;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutofillWindowPresenter;
 import android.widget.Toast;
 
@@ -60,8 +61,9 @@
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
-        void authenticate(int requestId, @NonNull IntentSender intent, @Nullable Bundle extras);
-        void fill(int requestId, @NonNull Dataset dataset);
+        void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent,
+                @Nullable Bundle extras);
+        void fill(int requestId, int datasetIndex, @NonNull Dataset dataset);
         void save();
         void cancelSave();
         void requestShowFillUi(AutofillId id, int width, int height,
@@ -74,31 +76,43 @@
         mContext = context;
     }
 
-    public void setCallback(@Nullable AutoFillUiCallback callback) {
+    public void setCallback(@NonNull AutoFillUiCallback callback) {
         mHandler.post(() -> {
             if (mCallback != callback) {
-                hideAllUiThread();
+                if (mCallback != null) {
+                    hideAllUiThread(mCallback);
+                }
+
                 mCallback = callback;
             }
         });
     }
 
+    public void clearCallback(@NonNull AutoFillUiCallback callback) {
+        mHandler.post(() -> {
+            if (mCallback == callback) {
+                hideAllUiThread(callback);
+                mCallback = null;
+            }
+        });
+    }
+
     /**
      * Displays an error message to the user.
      */
-    public void showError(int resId) {
-        showError(mContext.getString(resId));
+    public void showError(int resId, @NonNull AutoFillUiCallback callback) {
+        showError(mContext.getString(resId), callback);
     }
 
     /**
      * Displays an error message to the user.
      */
-    public void showError(@Nullable CharSequence message) {
+    public void showError(@Nullable CharSequence message, @NonNull AutoFillUiCallback callback) {
         mHandler.post(() -> {
-            if (!hasCallback()) {
+            if (mCallback != callback) {
                 return;
             }
-            hideAllUiThread();
+            hideAllUiThread(callback);
             if (!TextUtils.isEmpty(message)) {
                 Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
             }
@@ -108,8 +122,8 @@
     /**
      * Hides the fill UI.
      */
-    public void hideFillUi(AutofillId id) {
-        mHandler.post(this::hideFillUiUiThread);
+    public void hideFillUi(@NonNull AutoFillUiCallback callback) {
+        mHandler.post(() -> hideFillUiUiThread(callback));
     }
 
     /**
@@ -117,12 +131,12 @@
      *
      * @param filterText The filter prefix.
      */
-    public void filterFillUi(@Nullable String filterText) {
+    public void filterFillUi(@Nullable String filterText, @NonNull AutoFillUiCallback callback) {
         mHandler.post(() -> {
-            if (!hasCallback()) {
+            if (callback != mCallback) {
                 return;
             }
-            hideSaveUiUiThread();
+            hideSaveUiUiThread(callback);
             if (mFillUi != null) {
                 mFillUi.setFilterText(filterText);
             }
@@ -136,9 +150,11 @@
      * @param response the current fill response
      * @param filterText text of the view to be filled
      * @param packageName package name of the activity that is filled
+     * @param callback Identifier for the caller
      */
     public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
-            @Nullable String filterText, @NonNull String packageName) {
+            @Nullable String filterText, @NonNull String packageName,
+            @NonNull AutoFillUiCallback callback) {
         if (sDebug) {
             Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + filterText);
         }
@@ -150,18 +166,19 @@
                         response.getDatasets() == null ? 0 : response.getDatasets().size());
 
         mHandler.post(() -> {
-            if (!hasCallback()) {
+            if (callback != mCallback) {
                 return;
             }
-            hideAllUiThread();
+            hideAllUiThread(callback);
             mFillUi = new FillUi(mContext, response, focusedId,
                     filterText, new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
                     log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
-                    hideFillUiUiThread();
+                    hideFillUiUiThread(callback);
                     if (mCallback != null) {
                         mCallback.authenticate(response.getRequestId(),
+                                AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED,
                                 response.getAuthentication(), response.getClientState());
                     }
                 }
@@ -169,16 +186,17 @@
                 @Override
                 public void onDatasetPicked(Dataset dataset) {
                     log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
-                    hideFillUiUiThread();
+                    hideFillUiUiThread(callback);
                     if (mCallback != null) {
-                        mCallback.fill(response.getRequestId(), dataset);
+                        final int datasetIndex = response.getDatasets().indexOf(dataset);
+                        mCallback.fill(response.getRequestId(), datasetIndex, dataset);
                     }
                 }
 
                 @Override
                 public void onCanceled() {
                     log.setType(MetricsProto.MetricsEvent.TYPE_DISMISS);
-                    hideFillUiUiThread();
+                    hideFillUiUiThread(callback);
                 }
 
                 @Override
@@ -218,7 +236,7 @@
      * Shows the UI asking the user to save for autofill.
      */
     public void showSaveUi(@NonNull CharSequence providerLabel, @NonNull SaveInfo info,
-            @NonNull String packageName) {
+            @NonNull String packageName, @NonNull AutoFillUiCallback callback) {
         int numIds = 0;
         numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
         numIds += info.getOptionalIds() == null ? 0 : info.getOptionalIds().length;
@@ -228,16 +246,16 @@
                         MetricsProto.MetricsEvent.FIELD_AUTOFILL_NUM_IDS, numIds);
 
         mHandler.post(() -> {
-            if (!hasCallback()) {
+            if (callback != mCallback) {
                 return;
             }
-            hideAllUiThread();
+            hideAllUiThread(callback);
             mSaveUi = new SaveUi(mContext, providerLabel, info,
                     new SaveUi.OnSaveListener() {
                 @Override
                 public void onSave() {
                     log.setType(MetricsProto.MetricsEvent.TYPE_ACTION);
-                    hideSaveUiUiThread();
+                    hideSaveUiUiThread(callback);
                     if (mCallback != null) {
                         mCallback.save();
                     }
@@ -246,7 +264,7 @@
                 @Override
                 public void onCancel(IntentSender listener) {
                     log.setType(MetricsProto.MetricsEvent.TYPE_DISMISS);
-                    hideSaveUiUiThread();
+                    hideSaveUiUiThread(callback);
                     if (listener != null) {
                         try {
                             listener.sendIntent(mContext, 0, null, null, null);
@@ -264,6 +282,10 @@
                 public void onDestroy() {
                     if (log.getType() == MetricsProto.MetricsEvent.TYPE_UNKNOWN) {
                         log.setType(MetricsProto.MetricsEvent.TYPE_CLOSE);
+
+                        if (mCallback != null) {
+                            mCallback.cancelSave();
+                        }
                     }
                     mMetricsLogger.write(log);
                 }
@@ -274,46 +296,47 @@
     /**
      * Hides all UI affordances.
      */
-    public void hideAll() {
-        mHandler.post(this::hideAllUiThread);
+    public void hideAll(@Nullable AutoFillUiCallback callback) {
+        mHandler.post(() -> hideAllUiThread(callback));
     }
 
     public void dump(PrintWriter pw) {
         pw.println("Autofill UI");
         final String prefix = "  ";
         final String prefix2 = "    ";
-        pw.print(prefix); pw.print("showsSaveUi: "); pw.println(mSaveUi != null);
         if (mFillUi != null) {
             pw.print(prefix); pw.println("showsFillUi: true");
             mFillUi.dump(pw, prefix2);
         } else {
             pw.print(prefix); pw.println("showsFillUi: false");
         }
+        if (mSaveUi != null) {
+            pw.print(prefix); pw.println("showsSaveUi: true");
+            mSaveUi.dump(pw, prefix2);
+        } else {
+            pw.print(prefix); pw.println("showsSaveUi: false");
+        }
     }
 
     @android.annotation.UiThread
-    private void hideFillUiUiThread() {
-        if (mFillUi != null) {
+    private void hideFillUiUiThread(@Nullable AutoFillUiCallback callback) {
+        if (mFillUi != null && (callback == null || callback == mCallback)) {
             mFillUi.destroy();
             mFillUi = null;
         }
     }
 
     @android.annotation.UiThread
-    private void hideSaveUiUiThread() {
-        if (mSaveUi != null) {
+    private void hideSaveUiUiThread(@Nullable AutoFillUiCallback callback) {
+        if (mSaveUi != null && (callback == null || callback == mCallback)) {
             mSaveUi.destroy();
             mSaveUi = null;
         }
     }
 
     @android.annotation.UiThread
-    private void hideAllUiThread() {
-        hideFillUiUiThread();
-        hideSaveUiUiThread();
-    }
-
-    private boolean hasCallback() {
-        return mCallback != null;
+    private void hideAllUiThread(@Nullable AutoFillUiCallback callback) {
+        hideFillUiUiThread(callback);
+        hideSaveUiUiThread(callback);
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index dd297a6..d315b3d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -16,6 +16,7 @@
 package com.android.server.autofill.ui;
 
 import static com.android.server.autofill.Helper.sDebug;
+import static com.android.server.autofill.Helper.sVerbose;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -27,6 +28,7 @@
 import android.graphics.Rect;
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
@@ -35,10 +37,13 @@
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
-import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
 import android.widget.ListView;
 import android.widget.RemoteViews;
 
@@ -48,6 +53,8 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 final class FillUi {
     private static final String TAG = "FillUi";
@@ -80,10 +87,12 @@
 
     private final @NonNull ListView mListView;
 
-    private final @Nullable ArrayAdapter<ViewItem> mAdapter;
+    private final @Nullable ItemsAdapter mAdapter;
 
     private @Nullable String mFilterText;
 
+    private @Nullable AnnounceFilterResult mAnnounceFilterResult;
+
     private int mContentWidth;
     private int mContentHeight;
 
@@ -156,7 +165,9 @@
                     }
                     final AutofillValue value = dataset.getFieldValues().get(index);
                     String valueText = null;
-                    if (value.isText()) {
+                    // If the dataset needs auth - don't add its text to allow guessing
+                    // its content based on how filtering behaves.
+                    if (value != null && value.isText() && dataset.getAuthentication() == null) {
                         valueText = value.getTextValue().toString().toLowerCase();
                     }
 
@@ -164,12 +175,7 @@
                 }
             }
 
-            mAdapter = new ArrayAdapter<ViewItem>(context, 0, items) {
-                @Override
-                public View getView(int position, View convertView, ViewGroup parent) {
-                    return getItem(position).getView();
-                }
-            };
+            mAdapter = new ItemsAdapter(items);
 
             mListView = decor.findViewById(R.id.autofill_dataset_list);
             mListView.setAdapter(mAdapter);
@@ -265,9 +271,11 @@
         mContentWidth = 0;
         mContentHeight = 0;
 
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
-        final int itemCount = Math.min(mAdapter.getCount(), VISIBLE_OPTIONS_MAX_COUNT);
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.x,
+                MeasureSpec.AT_MOST);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
+                MeasureSpec.AT_MOST);
+        final int itemCount = mAdapter.getCount();
         for (int i = 0; i < itemCount; i++) {
             View view = mAdapter.getItem(i).getView();
             view.measure(widthMeasureSpec, heightMeasureSpec);
@@ -277,11 +285,14 @@
                 mContentWidth = newContentWidth;
                 changed = true;
             }
-            final int clampedMeasuredHeight = Math.min(view.getMeasuredHeight(), maxSize.y);
-            final int newContentHeight = mContentHeight + clampedMeasuredHeight;
-            if (newContentHeight != mContentHeight) {
-                mContentHeight = newContentHeight;
-                changed = true;
+            // Update the width to fit only the first items up to max count
+            if (i < VISIBLE_OPTIONS_MAX_COUNT) {
+                final int clampedMeasuredHeight = Math.min(view.getMeasuredHeight(), maxSize.y);
+                final int newContentHeight = mContentHeight + clampedMeasuredHeight;
+                if (newContentHeight != mContentHeight) {
+                    mContentHeight = newContentHeight;
+                    changed = true;
+                }
             }
         }
         return changed;
@@ -323,6 +334,10 @@
             return mDataset;
         }
 
+        public String getValue() {
+            return mValue;
+        }
+
         @Override
         public String toString() {
             // Used for filtering in the adapter
@@ -334,6 +349,11 @@
         @Override
         public void show(WindowManager.LayoutParams p, Rect transitionEpicenter,
                 boolean fitsSystemWindows, int layoutDirection) {
+            if (sVerbose) {
+                Slog.v(TAG, "AutofillWindowPresenter.show(): fit=" + fitsSystemWindows
+                        + ", epicenter="+ transitionEpicenter + ", dir=" + layoutDirection
+                        + ", params=" + p);
+            }
             UiThread.getHandler().post(() -> mWindow.show(p));
         }
 
@@ -398,6 +418,7 @@
             }
             return false;
         }
+
     }
 
     public void dump(PrintWriter pw, String prefix) {
@@ -408,5 +429,133 @@
         pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
         pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
         pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
+        pw.print(prefix); pw.print("mWindow: ");
+        if (mWindow == null) {
+            pw.println("N/A");
+        } else {
+            final String prefix2 = prefix + "  ";
+            pw.println();
+            pw.print(prefix2); pw.print("showing: "); pw.println(mWindow.mShowing);
+            pw.print(prefix2); pw.print("view: "); pw.println(mWindow.mContentView);
+            pw.print(prefix2); pw.print("screen coordinates: ");
+            if (mWindow.mContentView == null) {
+                pw.println("N/A");
+            } else {
+                final int[] coordinates = mWindow.mContentView.getLocationOnScreen();
+                pw.print(coordinates[0]); pw.print("x"); pw.println(coordinates[1]);
+            }
+        }
+    }
+
+    private void announceSearchResultIfNeeded() {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            if (mAnnounceFilterResult == null) {
+                mAnnounceFilterResult = new AnnounceFilterResult();
+            }
+            mAnnounceFilterResult.post();
+        }
+    }
+
+    private final class ItemsAdapter extends BaseAdapter implements Filterable {
+        private @NonNull final List<ViewItem> mAllItems;
+
+        private @NonNull final List<ViewItem> mFilteredItems = new ArrayList<>();
+
+        ItemsAdapter(@NonNull List<ViewItem> items) {
+            mAllItems = Collections.unmodifiableList(new ArrayList<>(items));
+            mFilteredItems.addAll(items);
+        }
+
+        @Override
+        public Filter getFilter() {
+            return new Filter() {
+                @Override
+                protected FilterResults performFiltering(CharSequence constraint) {
+                    // No locking needed as mAllItems is final an immutable
+                    final FilterResults results = new FilterResults();
+                    if (TextUtils.isEmpty(constraint)) {
+                        results.values = mAllItems;
+                        results.count = mAllItems.size();
+                        return results;
+                    }
+                    final List<ViewItem> filteredItems = new ArrayList<>();
+                    final String constraintLowerCase = constraint.toString().toLowerCase();
+                    final int itemCount = mAllItems.size();
+                    for (int i = 0; i < itemCount; i++) {
+                        final ViewItem item = mAllItems.get(i);
+                        final String value = item.getValue();
+                        // No value, i.e. null, matches any filter
+                        if (value == null
+                                || value.toLowerCase().contains(constraintLowerCase)) {
+                            filteredItems.add(item);
+                        }
+                    }
+                    results.values = filteredItems;
+                    results.count = filteredItems.size();
+                    return results;
+                }
+
+                @Override
+                protected void publishResults(CharSequence constraint, FilterResults results) {
+                    final boolean resultCountChanged;
+                    final int oldItemCount = mFilteredItems.size();
+                    mFilteredItems.clear();
+                    @SuppressWarnings("unchecked")
+                    final List<ViewItem> items = (List<ViewItem>) results.values;
+                    mFilteredItems.addAll(items);
+                    resultCountChanged = (oldItemCount != mFilteredItems.size());
+                    if (resultCountChanged) {
+                        announceSearchResultIfNeeded();
+                    }
+                    notifyDataSetChanged();
+                }
+            };
+        }
+
+        @Override
+        public int getCount() {
+            return mFilteredItems.size();
+        }
+
+        @Override
+        public ViewItem getItem(int position) {
+            return mFilteredItems.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            return getItem(position).getView();
+        }
+    }
+
+    private final class AnnounceFilterResult implements Runnable {
+        private static final int SEARCH_RESULT_ANNOUNCEMENT_DELAY = 1000; // 1 sec
+
+        public void post() {
+            remove();
+            mListView.postDelayed(this, SEARCH_RESULT_ANNOUNCEMENT_DELAY);
+        }
+
+        public void remove() {
+            mListView.removeCallbacks(this);
+        }
+
+        @Override
+        public void run() {
+            final int count = mListView.getAdapter().getCount();
+            final String text;
+            if (count <= 0) {
+                text = mContext.getString(R.string.autofill_picker_no_suggestions);
+            } else {
+                text = mContext.getResources().getQuantityString(
+                        R.plurals.autofill_picker_some_suggestions, count, count);
+            }
+            mListView.announceForAccessibility(text);
+        }
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index bcdb118..d25ffce 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -37,6 +37,8 @@
 import com.android.internal.R;
 import com.android.server.UiThread;
 
+import java.io.PrintWriter;
+
 /**
  * Autofill Save Prompt
  */
@@ -96,6 +98,9 @@
 
     private final @NonNull OneTimeListener mListener;
 
+    private final CharSequence mTitle;
+    private final CharSequence mSubTitle;
+
     private boolean mDestroyed;
 
     SaveUi(@NonNull Context context, @NonNull CharSequence providerLabel, @NonNull SaveInfo info,
@@ -126,37 +131,36 @@
             types.add(context.getString(R.string.autofill_save_type_email_address));
         }
 
-        final CharSequence title;
         switch (types.size()) {
             case 1:
-                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_type,
+                mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_type,
                         types.valueAt(0), providerLabel), 0);
                 break;
             case 2:
-                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_2types,
+                mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_2types,
                         types.valueAt(0), types.valueAt(1), providerLabel), 0);
                 break;
             case 3:
-                title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_3types,
+                mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_3types,
                         types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel), 0);
                 break;
             default:
                 // Use generic if more than 3 or invalid type (size 0).
-                title = Html.fromHtml(
+                mTitle = Html.fromHtml(
                         context.getString(R.string.autofill_save_title, providerLabel), 0);
         }
 
-        titleView.setText(title);
-        final CharSequence subTitle = info.getDescription();
-        if (subTitle != null) {
+        titleView.setText(mTitle);
+        mSubTitle = info.getDescription();
+        if (mSubTitle != null) {
             final TextView subTitleView = (TextView) view.findViewById(R.id.autofill_save_subtitle);
-            subTitleView.setText(subTitle);
+            subTitleView.setText(mSubTitle);
             subTitleView.setVisibility(View.VISIBLE);
         }
 
-        Slog.i(TAG, "Showing save dialog: " + title);
+        Slog.i(TAG, "Showing save dialog: " + mTitle);
         if (sDebug) {
-            Slog.d(TAG, "SubTitle: " + subTitle);
+            Slog.d(TAG, "SubTitle: " + mSubTitle);
         }
 
         final TextView noButton = view.findViewById(R.id.autofill_save_no);
@@ -207,4 +211,18 @@
             throw new IllegalStateException("cannot interact with a destroyed instance");
         }
     }
+
+    void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("title: "); pw.println(mTitle);
+        pw.print(prefix); pw.print("subtitle: "); pw.println(mSubTitle);
+
+        final View view = mDialog.getWindow().getDecorView();
+        final int[] loc = view.getLocationOnScreen();
+        pw.print(prefix); pw.print("coordinates: ");
+            pw.print('('); pw.print(loc[0]); pw.print(','); pw.print(loc[1]);pw.print(')');
+            pw.print('(');
+                pw.print(loc[0] + view.getWidth()); pw.print(',');
+                pw.print(loc[1] + view.getHeight());pw.println(')');
+        pw.print(prefix); pw.print("destroyed: "); pw.println(mDestroyed);
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/FileMetadata.java b/services/backup/java/com/android/server/backup/FileMetadata.java
index afddd3e..5465609 100644
--- a/services/backup/java/com/android/server/backup/FileMetadata.java
+++ b/services/backup/java/com/android/server/backup/FileMetadata.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.BackupAgent;
 import android.util.Slog;
 
@@ -34,6 +36,8 @@
     public long mode;                      // e.g. 0666 (actually int)
     public long mtime;                     // last mod time, UTC time_t (actually int)
     public long size;                      // bytes of content
+    public int version;                    // App version.
+    public boolean hasApk;                 // Whether backup file contains apk.
 
     @Override
     public String toString() {
@@ -78,7 +82,7 @@
         b.append(" :: ");
         b.append(path);
 
-        Slog.i(RefactoredBackupManagerService.TAG, b.toString());
+        Slog.i(TAG, b.toString());
     }
 
 }
diff --git a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
index 811b741..b57c0bc 100644
--- a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java
@@ -2078,12 +2078,6 @@
 
     // ----- Back up a set of applications via a worker thread -----
 
-    public enum BackupState {
-        INITIAL,
-        RUNNING_QUEUE,
-        FINAL
-    }
-
     public boolean isBackupOperationInProgress() {
         synchronized (mCurrentOpLock) {
             for (int i = 0; i < mCurrentOperations.size(); i++) {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 47ae206..3bf77e8 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -16,6 +16,19 @@
 
 package com.android.server.backup.fullbackup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
+
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
 import android.app.backup.BackupTransport;
@@ -91,9 +104,8 @@
 
                 if (mWriteManifest) {
                     final boolean writeWidgetData = mWidgetData != null;
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.d(RefactoredBackupManagerService.TAG,
-                                "Writing manifest for " + mPackage.packageName);
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
                     }
                     FullBackupUtils
                             .writeAppManifest(mPackage, backupManagerService.getPackageManager(),
@@ -121,30 +133,25 @@
                 }
 
                 final boolean isSharedStorage =
-                        mPackage.packageName.equals(
-                                RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE);
+                        mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
                 final long timeout = isSharedStorage ?
-                        RefactoredBackupManagerService.TIMEOUT_SHARED_BACKUP_INTERVAL :
-                        RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+                        TIMEOUT_SHARED_BACKUP_INTERVAL :
+                        TIMEOUT_FULL_BACKUP_INTERVAL;
 
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG,
-                            "Calling doFullBackup() on " + mPackage.packageName);
+                if (DEBUG) {
+                    Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
                 }
                 backupManagerService
                         .prepareOperationTimeout(mToken,
                                 timeout,
                                 mTimeoutMonitor /* in parent class */,
-                                RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT);
+                                OP_TYPE_BACKUP_WAIT);
                 mAgent.doFullBackup(mPipe, mQuota, mToken,
                         backupManagerService.getBackupManagerBinder());
             } catch (IOException e) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Error running full backup for " + mPackage.packageName);
+                Slog.e(TAG, "Error running full backup for " + mPackage.packageName);
             } catch (RemoteException e) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Remote agent vanished during full backup of "
-                                + mPackage.packageName);
+                Slog.e(TAG, "Remote agent vanished during full backup of " + mPackage.packageName);
             } finally {
                 try {
                     mPipe.close();
@@ -165,30 +172,27 @@
         mIncludeApks = alsoApks;
         mTimeoutMonitor = timeoutMonitor;
         mFilesDir = new File("/data/system");
-        mManifestFile = new File(mFilesDir,
-                RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME);
-        mMetadataFile = new File(mFilesDir,
-                RefactoredBackupManagerService.BACKUP_METADATA_FILENAME);
+        mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
+        mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
         mQuota = quota;
         mOpToken = opToken;
     }
 
     public int preflightCheck() throws RemoteException {
         if (mPreflightHook == null) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "No preflight check");
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "No preflight check");
             }
             return BackupTransport.TRANSPORT_OK;
         }
         if (initializeAgent()) {
             int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "preflight returned " + result);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "preflight returned " + result);
             }
             return result;
         } else {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Unable to bind to full agent for " + mPkg.packageName);
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
             return BackupTransport.AGENT_ERROR;
         }
     }
@@ -203,8 +207,7 @@
 
                 ApplicationInfo app = mPkg.applicationInfo;
                 final boolean isSharedStorage =
-                        mPkg.packageName.equals(
-                                RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE);
+                        mPkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
                 final boolean sendApk = mIncludeApks
                         && !isSharedStorage
                         && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
@@ -226,18 +229,15 @@
                 FullBackupUtils.routeSocketDataToOutput(pipes[0], mOutput);
 
                 if (!backupManagerService.waitUntilOperationComplete(mOpToken)) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Full backup failed on package " + mPkg.packageName);
+                    Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
                 } else {
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.d(RefactoredBackupManagerService.TAG,
-                                "Full package backup success: " + mPkg.packageName);
+                    if (MORE_DEBUG) {
+                        Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
                     }
                     result = BackupTransport.TRANSPORT_OK;
                 }
             } catch (IOException e) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Error backing up " + mPkg.packageName + ": " + e.getMessage());
+                Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
                 result = BackupTransport.AGENT_ERROR;
             } finally {
                 try {
@@ -252,13 +252,12 @@
                         }
                     }
                 } catch (IOException e) {
-                    Slog.w(RefactoredBackupManagerService.TAG, "Error bringing down backup stack");
+                    Slog.w(TAG, "Error bringing down backup stack");
                     result = BackupTransport.TRANSPORT_ERROR;
                 }
             }
         } else {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Unable to bind to full agent for " + mPkg.packageName);
+            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
         }
         tearDown();
         return result;
@@ -269,17 +268,15 @@
             try {
                 mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
             } catch (RemoteException e) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Remote exception while telling agent about quota exceeded");
+                Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
             }
         }
     }
 
     private boolean initializeAgent() {
         if (mAgent == null) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.d(RefactoredBackupManagerService.TAG,
-                        "Binding to full backup agent : " + mPkg.packageName);
+            if (MORE_DEBUG) {
+                Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
             }
             mAgent = backupManagerService.bindToAgentSynchronous(mPkg.applicationInfo,
                     ApplicationThreadConstants.BACKUP_MODE_FULL);
@@ -304,8 +301,8 @@
         final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_SYSTEM);
         final File obbDir = userEnv.buildExternalStorageAppObbDirs(pkg.packageName)[0];
         if (obbDir != null) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Log.i(RefactoredBackupManagerService.TAG, "obb dir: " + obbDir.getAbsolutePath());
+            if (MORE_DEBUG) {
+                Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
             }
             File[] obbFiles = obbDir.listFiles();
             if (obbFiles != null) {
@@ -338,7 +335,7 @@
             throws IOException {
         StringBuilder b = new StringBuilder(512);
         StringBuilderPrinter printer = new StringBuilderPrinter(b);
-        printer.println(Integer.toString(RefactoredBackupManagerService.BACKUP_METADATA_VERSION));
+        printer.println(Integer.toString(BACKUP_METADATA_VERSION));
         printer.println(pkg.packageName);
 
         FileOutputStream fout = new FileOutputStream(destination);
@@ -347,7 +344,7 @@
         bout.write(b.toString().getBytes());    // bypassing DataOutputStream
 
         if (widgetData != null && widgetData.length > 0) {
-            out.writeInt(RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN);
+            out.writeInt(BACKUP_WIDGET_METADATA_TOKEN);
             out.writeInt(widgetData.length);
             out.write(widgetData);
         }
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
index 34ff949..da8a66a 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -16,6 +16,11 @@
 
 package com.android.server.backup.fullbackup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
 import android.app.backup.IBackupManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -48,8 +53,8 @@
     }
 
     public void establish() {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(RefactoredBackupManagerService.TAG, "Initiating bind of OBB service on " + this);
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Initiating bind of OBB service on " + this);
         }
         Intent obbIntent = new Intent().setComponent(new ComponentName(
                 "com.android.sharedstoragebackup",
@@ -70,16 +75,14 @@
         try {
             pipes = ParcelFileDescriptor.createPipe();
             int token = backupManagerService.generateRandomIntegerToken();
-            backupManagerService
-                    .prepareOperationTimeout(token,
-                            RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                            null, RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT);
+            backupManagerService.prepareOperationTimeout(
+                    token, TIMEOUT_FULL_BACKUP_INTERVAL, null, OP_TYPE_BACKUP_WAIT);
             mService.backupObbs(pkg.packageName, pipes[1], token,
                     backupManagerService.getBackupManagerBinder());
             FullBackupUtils.routeSocketDataToOutput(pipes[0], out);
             success = backupManagerService.waitUntilOperationComplete(token);
         } catch (Exception e) {
-            Slog.w(RefactoredBackupManagerService.TAG, "Unable to back up OBBs for " + pkg, e);
+            Slog.w(TAG, "Unable to back up OBBs for " + pkg, e);
         } finally {
             try {
                 out.flush();
@@ -92,7 +95,7 @@
                     }
                 }
             } catch (IOException e) {
-                Slog.w(RefactoredBackupManagerService.TAG, "I/O error closing down OBB backup", e);
+                Slog.w(TAG, "I/O error closing down OBB backup", e);
             }
         }
         return success;
@@ -107,23 +110,22 @@
             mService.restoreObbFile(pkgName, data, fileSize, type, path, mode, mtime,
                     token, callbackBinder);
         } catch (Exception e) {
-            Slog.w(RefactoredBackupManagerService.TAG, "Unable to restore OBBs for " + pkgName, e);
+            Slog.w(TAG, "Unable to restore OBBs for " + pkgName, e);
         }
     }
 
     private void waitForConnection() {
         synchronized (this) {
             while (mService == null) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "...waiting for OBB service binding...");
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "...waiting for OBB service binding...");
                 }
                 try {
                     this.wait();
                 } catch (InterruptedException e) { /* never interrupted */ }
             }
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG, "Connected to OBB service; continuing");
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Connected to OBB service; continuing");
             }
         }
     }
@@ -132,9 +134,8 @@
     public void onServiceConnected(ComponentName name, IBinder service) {
         synchronized (this) {
             mService = IObbBackupService.Stub.asInterface(service);
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG, "OBB service connection " + mService
-                        + " connected on " + this);
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection " + mService + " connected on " + this);
             }
             this.notifyAll();
         }
@@ -144,9 +145,8 @@
     public void onServiceDisconnected(ComponentName name) {
         synchronized (this) {
             mService = null;
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "OBB service connection disconnected on " + this);
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "OBB service connection disconnected on " + this);
             }
             this.notifyAll();
         }
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
index 38ab0bf..37961f9 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupTask.java
@@ -16,12 +16,12 @@
 
 package com.android.server.backup.fullbackup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.IFullBackupRestoreObserver;
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 /**
  * Generic driver skeleton for full backup operations.
  */
@@ -39,8 +39,7 @@
             try {
                 mObserver.onStartBackup();
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full backup observer went away: startBackup");
+                Slog.w(TAG, "full backup observer went away: startBackup");
                 mObserver = null;
             }
         }
@@ -52,8 +51,7 @@
                 // TODO: use a more user-friendly name string
                 mObserver.onBackupPackage(name);
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full backup observer went away: backupPackage");
+                Slog.w(TAG, "full backup observer went away: backupPackage");
                 mObserver = null;
             }
         }
@@ -64,8 +62,7 @@
             try {
                 mObserver.onEndBackup();
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full backup observer went away: endBackup");
+                Slog.w(TAG, "full backup observer went away: endBackup");
                 mObserver = null;
             }
         }
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index 77961fc..007d930 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -16,6 +16,14 @@
 
 package com.android.server.backup.fullbackup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.IFullBackupRestoreObserver;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -108,9 +116,8 @@
         } else {
             mEncryptPassword = encryptPassword;
         }
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Encrypting backup with passphrase=" + mEncryptPassword);
+        if (MORE_DEBUG) {
+            Slog.w(TAG, "Encrypting backup with passphrase=" + mEncryptPassword);
         }
         mCompress = doCompress;
         mKeyValue = doKeyValue;
@@ -125,8 +132,7 @@
                             PackageManager.GET_SIGNATURES);
                     set.put(pkgName, info);
                 } catch (NameNotFoundException e) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Unknown package " + pkgName + ", skipping");
+                    Slog.w(TAG, "Unknown package " + pkgName + ", skipping");
                 }
             }
         }
@@ -138,7 +144,7 @@
         byte[] newUserSalt = backupManagerService
                 .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
         SecretKey userKey = PasswordUtils
-                .buildPasswordKey(RefactoredBackupManagerService.PBKDF_CURRENT, mEncryptPassword,
+                .buildPasswordKey(PBKDF_CURRENT, mEncryptPassword,
                         newUserSalt,
                         PasswordUtils.PBKDF2_HASH_ROUNDS);
 
@@ -188,7 +194,7 @@
         IV = c.getIV();
         byte[] mk = masterKeySpec.getEncoded();
         byte[] checksum = PasswordUtils
-                .makeKeyChecksum(RefactoredBackupManagerService.PBKDF_CURRENT,
+                .makeKeyChecksum(PBKDF_CURRENT,
                         masterKeySpec.getEncoded(),
                         checksumSalt, PasswordUtils.PBKDF2_HASH_ROUNDS);
 
@@ -215,16 +221,14 @@
             byte[] eof = new byte[512 * 2]; // newly allocated == zero filled
             out.write(eof);
         } catch (IOException e) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Error attempting to finalize backup stream");
+            Slog.w(TAG, "Error attempting to finalize backup stream");
         }
     }
 
     @Override
     public void run() {
         String includeKeyValue = mKeyValue ? ", including key-value backups" : "";
-        Slog.i(RefactoredBackupManagerService.TAG,
-                "--- Performing adb backup" + includeKeyValue + " ---");
+        Slog.i(TAG, "--- Performing adb backup" + includeKeyValue + " ---");
 
         TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<>();
         FullBackupObbConnection obbConnection = new FullBackupObbConnection(
@@ -255,16 +259,15 @@
             List<String> pkgs =
                     AppWidgetBackupBridge.getWidgetParticipants(UserHandle.USER_SYSTEM);
             if (pkgs != null) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "Adding widget participants to backup set:");
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Adding widget participants to backup set:");
                     StringBuilder sb = new StringBuilder(128);
                     sb.append("   ");
                     for (String s : pkgs) {
                         sb.append(' ');
                         sb.append(s);
                     }
-                    Slog.i(RefactoredBackupManagerService.TAG, sb.toString());
+                    Slog.i(TAG, sb.toString());
                 }
                 addPackagesToSet(packagesToBackup, pkgs);
             }
@@ -288,14 +291,14 @@
             if (!AppBackupUtils.appIsEligibleForBackup(pkg.applicationInfo)
                     || AppBackupUtils.appIsStopped(pkg.applicationInfo)) {
                 iter.remove();
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG, "Package " + pkg.packageName
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
                             + " is not eligible for backup, removing.");
                 }
             } else if (AppBackupUtils.appIsKeyValueOnly(pkg)) {
                 iter.remove();
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG, "Package " + pkg.packageName
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + pkg.packageName
                             + " is key-value.");
                 }
                 keyValueBackupQueue.add(pkg);
@@ -314,8 +317,7 @@
 
             // Only allow encrypted backups of encrypted devices
             if (backupManagerService.deviceIsEncrypted() && !encrypting) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Unencrypted backup of encrypted device; aborting");
+                Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
                 return;
             }
 
@@ -324,9 +326,8 @@
             // Verify that the given password matches the currently-active
             // backup password, if any
             if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Backup password mismatch; aborting");
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
                 }
                 return;
             }
@@ -358,9 +359,8 @@
             // archive's.
             StringBuilder headerbuf = new StringBuilder(1024);
 
-            headerbuf.append(RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC);
-            headerbuf.append(
-                    RefactoredBackupManagerService.BACKUP_FILE_VERSION); // integer, no trailing \n
+            headerbuf.append(BACKUP_FILE_HEADER_MAGIC);
+            headerbuf.append(BACKUP_FILE_VERSION); // integer, no trailing \n
             headerbuf.append(mCompress ? "\n1\n" : "\n0\n");
 
             try {
@@ -383,7 +383,7 @@
                 out = finalOutput;
             } catch (Exception e) {
                 // Should never happen!
-                Slog.e(RefactoredBackupManagerService.TAG, "Unable to emit archive header", e);
+                Slog.e(TAG, "Unable to emit archive header", e);
                 return;
             }
 
@@ -391,11 +391,10 @@
             if (mIncludeShared) {
                 try {
                     pkg = backupManagerService.getPackageManager().getPackageInfo(
-                            RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE, 0);
+                            SHARED_BACKUP_AGENT_PACKAGE, 0);
                     backupQueue.add(pkg);
                 } catch (NameNotFoundException e) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Unable to find shared-storage backup handler");
+                    Slog.e(TAG, "Unable to find shared-storage backup handler");
                 }
             }
 
@@ -403,14 +402,13 @@
             int N = backupQueue.size();
             for (int i = 0; i < N; i++) {
                 pkg = backupQueue.get(i);
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "--- Performing full backup for package " + pkg.packageName
-                                    + " ---");
+                if (DEBUG) {
+                    Slog.i(TAG, "--- Performing full backup for package " + pkg.packageName
+                            + " ---");
                 }
                 final boolean isSharedStorage =
                         pkg.packageName.equals(
-                                RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE);
+                                SHARED_BACKUP_AGENT_PACKAGE);
 
                 mBackupEngine = new FullBackupEngine(backupManagerService, out,
                         null, pkg, mIncludeApks, this, Long.MAX_VALUE, mCurrentOpToken);
@@ -432,10 +430,9 @@
             // And for key-value backup if enabled
             if (mKeyValue) {
                 for (PackageInfo keyValuePackage : keyValueBackupQueue) {
-                    if (RefactoredBackupManagerService.DEBUG) {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "--- Performing key-value backup for package "
-                                        + keyValuePackage.packageName + " ---");
+                    if (DEBUG) {
+                        Slog.i(TAG, "--- Performing key-value backup for package "
+                                + keyValuePackage.packageName + " ---");
                     }
                     KeyValueAdbBackupEngine kvBackupEngine =
                             new KeyValueAdbBackupEngine(out, keyValuePackage,
@@ -451,9 +448,9 @@
             // Done!
             finalizeBackup(out);
         } catch (RemoteException e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "App died during full backup");
+            Slog.e(TAG, "App died during full backup");
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "Internal exception during full backup", e);
+            Slog.e(TAG, "Internal exception during full backup", e);
         } finally {
             try {
                 if (out != null) {
@@ -470,8 +467,8 @@
             }
             sendEndBackup();
             obbConnection.tearDown();
-            if (RefactoredBackupManagerService.DEBUG) {
-                Slog.d(RefactoredBackupManagerService.TAG, "Full backup pass complete.");
+            if (DEBUG) {
+                Slog.d(TAG, "Full backup pass complete.");
             }
             backupManagerService.getWakelock().release();
         }
@@ -491,8 +488,8 @@
     @Override
     public void handleCancel(boolean cancelAll) {
         final PackageInfo target = mCurrentTarget;
-        if (RefactoredBackupManagerService.DEBUG) {
-            Slog.w(RefactoredBackupManagerService.TAG, "adb backup cancel of " + target);
+        if (DEBUG) {
+            Slog.w(TAG, "adb backup cancel of " + target);
         }
         if (target != null) {
             backupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 1c1248e..0f1e485 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -16,6 +16,14 @@
 
 package com.android.server.backup.fullbackup;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_SCHEDULING;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
 import android.app.IBackupAgent;
 import android.app.backup.BackupManager;
 import android.app.backup.BackupManagerMonitor;
@@ -121,7 +129,7 @@
         mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
 
         if (backupManagerService.isBackupOperationInProgress()) {
-            if (RefactoredBackupManagerService.DEBUG) {
+            if (DEBUG) {
                 Slog.d(TAG, "Skipping full backup. A backup is already in progress.");
             }
             mCancelAll = true;
@@ -140,7 +148,7 @@
                     // that run as system-domain uids but do not define their own backup agents,
                     // as well as any explicit mention of the 'special' shared-storage agent
                     // package (we handle that one at the end).
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "Ignoring ineligible package " + pkg);
                     }
                     mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -154,7 +162,7 @@
                 } else if (!AppBackupUtils.appGetsFullBackup(info)) {
                     // Cull any packages that are found in the queue but now aren't supposed
                     // to get full-data backup operations.
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "Ignoring full-data backup of key/value participant "
                                 + pkg);
                     }
@@ -170,7 +178,7 @@
                     // Cull any packages in the 'stopped' state: they've either just been
                     // installed or have explicitly been force-stopped by the user.  In both
                     // cases we do not want to launch them for backup.
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "Ignoring stopped package " + pkg);
                     }
                     mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -197,9 +205,9 @@
     private void registerTask() {
         synchronized (backupManagerService.getCurrentOpLock()) {
             Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
-            backupManagerService.getCurrentOperations().put(mCurrentOpToken, new Operation(
-                    RefactoredBackupManagerService.OP_PENDING, this,
-                    RefactoredBackupManagerService.OP_TYPE_BACKUP));
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken,
+                    new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
         }
     }
 
@@ -262,7 +270,7 @@
         try {
             if (!backupManagerService.isEnabled() || !backupManagerService.isProvisioned()) {
                 // Backups are globally disabled, so don't proceed.
-                if (RefactoredBackupManagerService.DEBUG) {
+                if (DEBUG) {
                     Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
                             .isEnabled()
                             + " provisioned=" + backupManagerService.isProvisioned()
@@ -300,7 +308,7 @@
             for (int i = 0; i < N; i++) {
                 PackageInfo currentPackage = mPackages.get(i);
                 String packageName = currentPackage.packageName;
-                if (RefactoredBackupManagerService.DEBUG) {
+                if (DEBUG) {
                     Slog.i(TAG, "Initiating full-data transport backup of " + packageName
                             + " token: " + mCurrentOpToken);
                 }
@@ -356,7 +364,7 @@
                     final long preflightResult = mBackupRunner.getPreflightResultBlocking();
                     // Preflight result is negative if some error happened on preflight.
                     if (preflightResult < 0) {
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
+                        if (MORE_DEBUG) {
                             Slog.d(TAG, "Backup error after preflight of package "
                                     + packageName + ": " + preflightResult
                                     + ", not running backup.");
@@ -373,7 +381,7 @@
                         int nRead = 0;
                         do {
                             nRead = in.read(buffer);
-                            if (RefactoredBackupManagerService.MORE_DEBUG) {
+                            if (MORE_DEBUG) {
                                 Slog.v(TAG, "in.read(buffer) from app: " + nRead);
                             }
                             if (nRead > 0) {
@@ -443,12 +451,12 @@
                             backupPackageStatus = backupRunnerResult;
                         }
                     } else {
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
+                        if (MORE_DEBUG) {
                             Slog.i(TAG, "Transport-level failure; cancelling agent work");
                         }
                     }
 
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.i(TAG, "Done delivering backup data: result="
                                 + backupPackageStatus);
                     }
@@ -461,7 +469,7 @@
                     // Also ask the transport how long it wants us to wait before
                     // moving on to the next package, if any.
                     backoff = mTransport.requestFullBackupTime();
-                    if (RefactoredBackupManagerService.DEBUG_SCHEDULING) {
+                    if (DEBUG_SCHEDULING) {
                         Slog.i(TAG, "Transport suggested backoff=" + backoff);
                     }
 
@@ -477,7 +485,7 @@
                     BackupObserverUtils
                             .sendBackupOnPackageResult(mBackupObserver, packageName,
                                     BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
-                    if (RefactoredBackupManagerService.DEBUG) {
+                    if (DEBUG) {
                         Slog.i(TAG, "Transport rejected backup of " + packageName
                                 + ", skipping");
                     }
@@ -488,7 +496,7 @@
                     BackupObserverUtils
                             .sendBackupOnPackageResult(mBackupObserver, packageName,
                                     BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
-                    if (RefactoredBackupManagerService.DEBUG) {
+                    if (DEBUG) {
                         Slog.i(TAG, "Transport quota exceeded for package: " + packageName);
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
                                 packageName);
@@ -556,7 +564,7 @@
                 backupRunStatus = BackupManager.ERROR_BACKUP_CANCELLED;
             }
 
-            if (RefactoredBackupManagerService.DEBUG) {
+            if (DEBUG) {
                 Slog.i(TAG, "Full backup completed with status: " + backupRunStatus);
             }
             BackupObserverUtils.sendBackupFinished(mBackupObserver, backupRunStatus);
@@ -582,7 +590,7 @@
                 backupManagerService.scheduleNextFullBackupJob(backoff);
             }
 
-            Slog.i(RefactoredBackupManagerService.TAG, "Full data backup pass finished.");
+            Slog.i(TAG, "Full data backup pass finished.");
             backupManagerService.getWakelock().release();
         }
     }
@@ -630,12 +638,10 @@
         public int preflightFullBackup(PackageInfo pkg, IBackupAgent agent) {
             int result;
             try {
-                backupManagerService
-                        .prepareOperationTimeout(mCurrentOpToken,
-                                RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                                this, RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT);
+                backupManagerService.prepareOperationTimeout(
+                        mCurrentOpToken, TIMEOUT_FULL_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
                 backupManagerService.addBackupTrace("preflighting");
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
                 }
                 agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
@@ -646,21 +652,20 @@
                 // timeout had been produced.  In case of a real backstop timeout, mResult
                 // will still contain the value it was constructed with, AGENT_ERROR, which
                 // intentionaly falls into the "just report failure" code.
-                mLatch.await(RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                        TimeUnit.MILLISECONDS);
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
 
                 long totalSize = mResult.get();
                 // If preflight timed out, mResult will contain error code as int.
                 if (totalSize < 0) {
                     return (int) totalSize;
                 }
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.v(TAG, "Got preflight response; size=" + totalSize);
                 }
 
                 result = mTransport.checkFullBackupSize(totalSize);
                 if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "Package hit quota limit on preflight " +
                                 pkg.packageName + ": " + totalSize + " of " + mQuota);
                     }
@@ -681,7 +686,7 @@
         @Override
         public void operationComplete(long result) {
             // got the callback, and our preflightFullBackup() method is waiting for the result
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
+            if (MORE_DEBUG) {
                 Slog.i(TAG, "Preflight op complete, result=" + result);
             }
             mResult.set(result);
@@ -691,7 +696,7 @@
 
         @Override
         public void handleCancel(boolean cancelAll) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
+            if (MORE_DEBUG) {
                 Slog.i(TAG, "Preflight cancelled; failing");
             }
             mResult.set(BackupTransport.AGENT_ERROR);
@@ -702,8 +707,7 @@
         @Override
         public long getExpectedSizeOrErrorCode() {
             try {
-                mLatch.await(RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                        TimeUnit.MILLISECONDS);
+                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
                 return mResult.get();
             } catch (InterruptedException e) {
                 return BackupTransport.NO_MORE_DATA;
@@ -742,9 +746,8 @@
 
         void registerTask() {
             synchronized (backupManagerService.getCurrentOpLock()) {
-                backupManagerService.getCurrentOperations().put(mCurrentOpToken, new Operation(
-                        RefactoredBackupManagerService.OP_PENDING, this,
-                        RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT));
+                backupManagerService.getCurrentOperations().put(
+                        mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
             }
         }
 
@@ -794,8 +797,7 @@
         // otherwise return negative error code.
         long getPreflightResultBlocking() {
             try {
-                mPreflightLatch.await(RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                        TimeUnit.MILLISECONDS);
+                mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
                 if (mIsCancelled) {
                     return BackupManager.ERROR_BACKUP_CANCELLED;
                 }
@@ -811,8 +813,7 @@
 
         int getBackupResultBlocking() {
             try {
-                mBackupLatch.await(RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                        TimeUnit.MILLISECONDS);
+                mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
                 if (mIsCancelled) {
                     return BackupManager.ERROR_BACKUP_CANCELLED;
                 }
@@ -833,7 +834,7 @@
 
         @Override
         public void handleCancel(boolean cancelAll) {
-            if (RefactoredBackupManagerService.DEBUG) {
+            if (DEBUG) {
                 Slog.w(TAG, "Full backup cancel of " + mTarget.packageName);
             }
 
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index c83041b..886d1f8 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -16,6 +16,11 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+
 import android.app.AlarmManager;
 import android.app.backup.RestoreSet;
 import android.content.Intent;
@@ -93,8 +98,7 @@
                 IBackupTransport transport =
                         backupManagerService.getTransportManager().getCurrentTransportBinder();
                 if (transport == null) {
-                    Slog.v(RefactoredBackupManagerService.TAG,
-                            "Backup requested but no transport available");
+                    Slog.v(TAG, "Backup requested but no transport available");
                     synchronized (backupManagerService.getQueueLock()) {
                         backupManagerService.setBackupRunning(false);
                     }
@@ -113,8 +117,8 @@
                         for (BackupRequest b : backupManagerService.getPendingBackups().values()) {
                             queue.add(b);
                         }
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.v(RefactoredBackupManagerService.TAG, "clearing pending backups");
+                        if (DEBUG) {
+                            Slog.v(TAG, "clearing pending backups");
                         }
                         backupManagerService.getPendingBackups().clear();
 
@@ -143,14 +147,12 @@
                     } catch (Exception e) {
                         // unable to ask the transport its dir name -- transient failure, since
                         // the above check succeeded.  Try again next time.
-                        Slog.e(RefactoredBackupManagerService.TAG,
-                                "Transport became unavailable attempting backup"
-                                        + " or error initializing backup task", e);
+                        Slog.e(TAG, "Transport became unavailable attempting backup"
+                                + " or error initializing backup task", e);
                         staged = false;
                     }
                 } else {
-                    Slog.v(RefactoredBackupManagerService.TAG,
-                            "Backup requested but nothing pending");
+                    Slog.v(TAG, "Backup requested but nothing pending");
                     staged = false;
                 }
 
@@ -167,14 +169,12 @@
             case MSG_BACKUP_RESTORE_STEP: {
                 try {
                     BackupRestoreTask task = (BackupRestoreTask) msg.obj;
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.v(RefactoredBackupManagerService.TAG,
-                                "Got next step for " + task + ", executing");
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Got next step for " + task + ", executing");
                     }
                     task.execute();
                 } catch (ClassCastException e) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Invalid backup task in flight, obj=" + msg.obj);
+                    Slog.e(TAG, "Invalid backup task in flight, obj=" + msg.obj);
                 }
                 break;
             }
@@ -185,8 +185,7 @@
                             (Pair<BackupRestoreTask, Long>) msg.obj;
                     taskWithResult.first.operationComplete(taskWithResult.second);
                 } catch (ClassCastException e) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Invalid completion in flight, obj=" + msg.obj);
+                    Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
                 }
                 break;
             }
@@ -213,8 +212,7 @@
 
             case MSG_RUN_RESTORE: {
                 RestoreParams params = (RestoreParams) msg.obj;
-                Slog.d(RefactoredBackupManagerService.TAG,
-                        "MSG_RUN_RESTORE observer=" + params.observer);
+                Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
 
                 PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(backupManagerService,
                         params.transport,
@@ -223,16 +221,15 @@
 
                 synchronized (backupManagerService.getPendingRestores()) {
                     if (backupManagerService.isRestoreInProgress()) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Restore in progress, queueing.");
+                        if (DEBUG) {
+                            Slog.d(TAG, "Restore in progress, queueing.");
                         }
                         backupManagerService.getPendingRestores().add(task);
                         // This task will be picked up and executed when the the currently running
                         // restore task finishes.
                     } else {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG, "Starting restore.");
+                        if (DEBUG) {
+                            Slog.d(TAG, "Starting restore.");
                         }
                         backupManagerService.setRestoreInProgress(true);
                         Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
@@ -305,26 +302,21 @@
                         EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                     }
                 } catch (Exception e) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Error from transport getting set list: " + e.getMessage());
+                    Slog.e(TAG, "Error from transport getting set list: " + e.getMessage());
                 } finally {
                     if (params.observer != null) {
                         try {
                             params.observer.restoreSetsAvailable(sets);
                         } catch (RemoteException re) {
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Unable to report listing to observer");
+                            Slog.e(TAG, "Unable to report listing to observer");
                         } catch (Exception e) {
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Restore observer threw: " + e.getMessage());
+                            Slog.e(TAG, "Restore observer threw: " + e.getMessage());
                         }
                     }
 
                     // Done: reset the session timeout clock
                     removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
-                    sendEmptyMessageDelayed(
-                            MSG_RESTORE_SESSION_TIMEOUT,
-                            RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL);
+                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
 
                     backupManagerService.getWakelock().release();
                 }
@@ -333,8 +325,7 @@
 
             case MSG_BACKUP_OPERATION_TIMEOUT:
             case MSG_RESTORE_OPERATION_TIMEOUT: {
-                Slog.d(RefactoredBackupManagerService.TAG,
-                        "Timeout message received for token=" + Integer.toHexString(msg.arg1));
+                Slog.d(TAG, "Timeout message received for token=" + Integer.toHexString(msg.arg1));
                 backupManagerService.handleCancel(msg.arg1, false);
                 break;
             }
@@ -346,8 +337,7 @@
                         // can't be in the middle of an actual restore operation because
                         // the timeout is suspended while a restore is in progress.  Clean
                         // up now.
-                        Slog.w(RefactoredBackupManagerService.TAG,
-                                "Restore session timed out; aborting");
+                        Slog.w(TAG, "Restore session timed out; aborting");
                         backupManagerService.getActiveRestoreSession().markTimedOut();
                         post(backupManagerService.getActiveRestoreSession().new EndRestoreRunnable(
                                 backupManagerService,
@@ -362,8 +352,7 @@
                     AdbParams params = backupManagerService.getAdbBackupRestoreConfirmations().get(
                             msg.arg1);
                     if (params != null) {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "Full backup/restore timed out waiting for user confirmation");
+                        Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation");
 
                         // Release the waiter; timeout == completion
                         backupManagerService.signalAdbBackupRestoreCompletion(params);
@@ -380,8 +369,7 @@
                             }
                         }
                     } else {
-                        Slog.d(RefactoredBackupManagerService.TAG,
-                                "couldn't find params for token " + msg.arg1);
+                        Slog.d(TAG, "couldn't find params for token " + msg.arg1);
                     }
                 }
                 break;
@@ -395,9 +383,8 @@
 
             case MSG_REQUEST_BACKUP: {
                 BackupParams params = (BackupParams) msg.obj;
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG,
-                            "MSG_REQUEST_BACKUP observer=" + params.observer);
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer);
                 }
                 ArrayList<BackupRequest> kvQueue = new ArrayList<>();
                 for (String packageName : params.kvPackages) {
@@ -418,9 +405,8 @@
 
             case MSG_SCHEDULE_BACKUP_PACKAGE: {
                 String pkgName = (String) msg.obj;
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG,
-                            "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_SCHEDULE_BACKUP_PACKAGE " + pkgName);
                 }
                 backupManagerService.dataChangedImpl(pkgName);
                 break;
diff --git a/services/backup/java/com/android/server/backup/internal/BackupState.java b/services/backup/java/com/android/server/backup/internal/BackupState.java
new file mode 100644
index 0000000..4d42c240
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/internal/BackupState.java
@@ -0,0 +1,10 @@
+package com.android.server.backup.internal;
+
+/**
+ * Current state of the backup.
+ */
+enum BackupState {
+    INITIAL,
+    RUNNING_QUEUE,
+    FINAL
+}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 51c3451..a996e2d 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -16,6 +16,15 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG_BACKUP_TRACE;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_PENDING;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_BACKUP_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
 
@@ -51,7 +60,6 @@
 import com.android.server.backup.KeyValueBackupJob;
 import com.android.server.backup.PackageManagerBackupAgent;
 import com.android.server.backup.RefactoredBackupManagerService;
-import com.android.server.backup.RefactoredBackupManagerService.BackupState;
 import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
 import com.android.server.backup.utils.AppBackupUtils;
 import com.android.server.backup.utils.BackupManagerMonitorUtils;
@@ -155,7 +163,7 @@
 
         synchronized (backupManagerService.getCurrentOpLock()) {
             if (backupManagerService.isBackupOperationInProgress()) {
-                if (RefactoredBackupManagerService.DEBUG) {
+                if (DEBUG) {
                     Slog.d(TAG, "Skipping backup since one is already in progress.");
                 }
                 mCancelAll = true;
@@ -186,9 +194,8 @@
      */
     private void registerTask() {
         synchronized (backupManagerService.getCurrentOpLock()) {
-            backupManagerService.getCurrentOperations().put(mCurrentOpToken, new Operation(
-                    RefactoredBackupManagerService.OP_PENDING, this,
-                    RefactoredBackupManagerService.OP_TYPE_BACKUP));
+            backupManagerService.getCurrentOperations().put(
+                    mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
         }
     }
 
@@ -229,7 +236,7 @@
     // We're starting a backup pass.  Initialize the transport and send
     // the PM metadata blob if we haven't already.
     void beginBackup() {
-        if (RefactoredBackupManagerService.DEBUG_BACKUP_TRACE) {
+        if (DEBUG_BACKUP_TRACE) {
             backupManagerService.clearBackupTrace();
             StringBuilder b = new StringBuilder(256);
             b.append("beginBackup: [");
@@ -267,9 +274,9 @@
         // we performed a backup.  Drop it from the working queue now that
         // we're committed to evaluating it for backup regardless.
         for (int i = 0; i < mQueue.size(); i++) {
-            if (RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL.equals(
+            if (PACKAGE_MANAGER_SENTINEL.equals(
                     mQueue.get(i).packageName)) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.i(TAG, "Metadata in queue; eliding");
                 }
                 mQueue.remove(i);
@@ -278,12 +285,11 @@
             }
         }
 
-        if (RefactoredBackupManagerService.DEBUG) {
-            Slog.v(TAG,
-                    "Beginning backup of " + mQueue.size() + " targets");
+        if (DEBUG) {
+            Slog.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
         }
 
-        File pmState = new File(mStateDir, RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL);
+        File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
         try {
             final String transportName = mTransport.transportDirName();
             EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
@@ -317,7 +323,7 @@
                     PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(
                             backupManagerService.getPackageManager());
                     mStatus = invokeAgentForBackup(
-                            RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL,
+                            PACKAGE_MANAGER_SENTINEL,
                             IBackupAgent.Stub.asInterface(pmAgent.onBind()), mTransport);
                     backupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
 
@@ -365,7 +371,7 @@
         // Sanity check that we have work to do.  If not, skip to the end where
         // we reestablish the wakelock invariants etc.
         if (mQueue.isEmpty()) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) Slog.i(TAG, "queue now empty");
+            if (MORE_DEBUG) Slog.i(TAG, "queue now empty");
             executeNextState(BackupState.FINAL);
             return;
         }
@@ -471,10 +477,9 @@
                 // An agent-level failure means we reenqueue this one agent for
                 // a later retry, but otherwise proceed normally.
                 if (mStatus == BackupTransport.AGENT_ERROR) {
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.i(TAG,
-                                "Agent failure for " + request.packageName
-                                        + " - restaging");
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Agent failure for " + request.packageName
+                                + " - restaging");
                     }
                     backupManagerService.dataChangedImpl(request.packageName);
                     mStatus = BackupTransport.TRANSPORT_OK;
@@ -544,9 +549,8 @@
             backupManagerService.setBackupRunning(false);
             if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
                 // Make sure we back up everything and perform the one-time init
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.d(TAG,
-                            "Server requires init; rerunning");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Server requires init; rerunning");
                 }
                 backupManagerService.addBackupTrace("init required; rerunning");
                 try {
@@ -555,7 +559,7 @@
                     if (name != null) {
                         backupManagerService.getPendingInits().add(name);
                     } else {
-                        if (RefactoredBackupManagerService.DEBUG) {
+                        if (DEBUG) {
                             Slog.w(TAG, "Couldn't find name of transport " + mTransport
                                     + " for init");
                         }
@@ -603,15 +607,14 @@
                     break;
             }
         }
-        Slog.i(RefactoredBackupManagerService.TAG, "K/V backup pass finished.");
+        Slog.i(TAG, "K/V backup pass finished.");
         // Only once we're entirely finished do we release the wakelock for k/v backup.
         backupManagerService.getWakelock().release();
     }
 
     // Remove the PM metadata state. This will generate an init on the next pass.
     void clearMetadata() {
-        final File pmState = new File(mStateDir,
-                RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL);
+        final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
         if (pmState.exists()) pmState.delete();
     }
 
@@ -619,9 +622,8 @@
     // handler in case it doesn't get back to us.
     int invokeAgentForBackup(String packageName, IBackupAgent agent,
             IBackupTransport transport) {
-        if (RefactoredBackupManagerService.DEBUG) {
-            Slog.d(TAG,
-                    "invokeAgentForBackup on " + packageName);
+        if (DEBUG) {
+            Slog.d(TAG, "invokeAgentForBackup on " + packageName);
         }
         backupManagerService.addBackupTrace("invoking " + packageName);
 
@@ -629,7 +631,7 @@
         mSavedStateName = new File(mStateDir, packageName);
         mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".data");
         mNewStateName = new File(mStateDir, packageName + ".new");
-        if (RefactoredBackupManagerService.MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
+        if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
 
         mSavedState = null;
         mBackupData = null;
@@ -641,7 +643,7 @@
             // Look up the package info & signatures.  This is first so that if it
             // throws an exception, there's no file setup yet that would need to
             // be unraveled.
-            if (packageName.equals(RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL)) {
+            if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) {
                 // The metadata 'package' is synthetic; construct one and make
                 // sure our global state is pointed at it
                 mCurrentPackage = new PackageInfo();
@@ -675,10 +677,8 @@
 
             // Initiate the target's backup pass
             backupManagerService.addBackupTrace("setting timeout");
-            backupManagerService
-                    .prepareOperationTimeout(mEphemeralOpToken,
-                            RefactoredBackupManagerService.TIMEOUT_BACKUP_INTERVAL, this,
-                            RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT);
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
             backupManagerService.addBackupTrace("calling agent doBackup()");
 
             agent.doBackup(mSavedState, mBackupData, mNewState, quota, mEphemeralOpToken,
@@ -740,7 +740,7 @@
         final File widgetFile = new File(mStateDir, pkgName + "_widget");
         final boolean priorStateExists = widgetFile.exists();
 
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
+        if (MORE_DEBUG) {
             if (priorStateExists || widgetState != null) {
                 Slog.i(TAG, "Checking widget update: state=" + (widgetState != null)
                         + " prior=" + priorStateExists);
@@ -783,12 +783,11 @@
                 stateOut.writeUTF(newChecksum);
             }
 
-            out.writeEntityHeader(RefactoredBackupManagerService.KEY_WIDGET_STATE,
-                    widgetState.length);
+            out.writeEntityHeader(KEY_WIDGET_STATE, widgetState.length);
             out.writeEntityData(widgetState, widgetState.length);
         } else {
             // Widget state for this app has been removed; commit a deletion
-            out.writeEntityHeader(RefactoredBackupManagerService.KEY_WIDGET_STATE, -1);
+            out.writeEntityHeader(KEY_WIDGET_STATE, -1);
             widgetFile.delete();
         }
     }
@@ -811,7 +810,7 @@
                 // initiated the appropriate next operation.
                 final String pkg = (mCurrentPackage != null)
                         ? mCurrentPackage.packageName : "[none]";
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.i(TAG, "Callback after agent teardown: " + pkg);
                 }
                 backupManagerService.addBackupTrace("late opComplete; curPkg = " + pkg);
@@ -882,10 +881,9 @@
             }
 
             // Spin the data off to the transport and proceed with the next stage.
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(TAG,
-                        "operationComplete(): sending data to transport for "
-                                + pkgName);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "operationComplete(): sending data to transport for "
+                        + pkgName);
             }
             backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_OPERATION_TIMEOUT);
             clearAgentState();
@@ -919,9 +917,8 @@
                         backupManagerService.addBackupTrace("transport rejected package");
                     }
                 } else {
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.i(TAG,
-                                "no backup data written; not calling transport");
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "no backup data written; not calling transport");
                     }
                     backupManagerService.addBackupTrace("no data to send");
                     mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -979,7 +976,7 @@
                 // otherwise we're done.
                 nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
             } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.d(TAG, "Package " + mCurrentPackage.packageName +
                             " hit quota limit on k/v backup");
                 }
@@ -1012,7 +1009,7 @@
         synchronized (mCancelLock) {
             if (mFinished) {
                 // We have already cancelled this operation.
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     Slog.d(TAG, "Ignoring stale cancel. cancelAll=" + cancelAll);
                 }
                 return;
@@ -1047,9 +1044,8 @@
     }
 
     void revertAndEndBackup() {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(TAG,
-                    "Reverting backup queue - restaging everything");
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Reverting backup queue - restaging everything");
         }
         backupManagerService.addBackupTrace("transport error; reverting");
 
@@ -1109,7 +1105,7 @@
     }
 
     void executeNextState(BackupState nextState) {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
+        if (MORE_DEBUG) {
             Slog.i(TAG, " => executing next step on "
                     + this + " nextState=" + nextState);
         }
diff --git a/services/backup/java/com/android/server/backup/internal/PerformClearTask.java b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
index 28dc766..7af01ea 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformClearTask.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.content.pm.PackageInfo;
 import android.util.Slog;
 
@@ -49,16 +51,14 @@
             // TODO - need to handle failures
             mTransport.clearBackupData(mPackage);
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Transport threw clearing data for " + mPackage + ": " + e.getMessage());
+            Slog.e(TAG, "Transport threw clearing data for " + mPackage + ": " + e.getMessage());
         } finally {
             try {
                 // TODO - need to handle failures
                 mTransport.finishBackup();
             } catch (Exception e) {
                 // Nothing we can do here, alas
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Unable to mark clear operation finished: " + e.getMessage());
+                Slog.e(TAG, "Unable to mark clear operation finished: " + e.getMessage());
             }
 
             // Last but not least, release the cpu
diff --git a/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
index f7bf8d9..5a75b66 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformInitializeTask.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.AlarmManager;
 import android.app.backup.BackupTransport;
 import android.os.SystemClock;
@@ -47,14 +49,11 @@
                         backupManagerService.getTransportManager().getTransportBinder(
                                 transportName);
                 if (transport == null) {
-                    Slog.e(
-                            RefactoredBackupManagerService.TAG,
-                            "Requested init for " + transportName + " but not found");
+                    Slog.e(TAG, "Requested init for " + transportName + " but not found");
                     continue;
                 }
 
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "Initializing (wiping) backup transport storage: " + transportName);
+                Slog.i(TAG, "Initializing (wiping) backup transport storage: " + transportName);
                 EventLog.writeEvent(EventLogTags.BACKUP_START, transport.transportDirName());
                 long startRealtime = SystemClock.elapsedRealtime();
                 int status = transport.initializeDevice();
@@ -65,7 +64,7 @@
 
                 // Okay, the wipe really happened.  Clean up our local bookkeeping.
                 if (status == BackupTransport.TRANSPORT_OK) {
-                    Slog.i(RefactoredBackupManagerService.TAG, "Device init successful");
+                    Slog.i(TAG, "Device init successful");
                     int millis = (int) (SystemClock.elapsedRealtime() - startRealtime);
                     EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
                     backupManagerService
@@ -78,23 +77,21 @@
                 } else {
                     // If this didn't work, requeue this one and try again
                     // after a suitable interval
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Transport error in initializeDevice()");
+                    Slog.e(TAG, "Transport error in initializeDevice()");
                     EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
                     synchronized (backupManagerService.getQueueLock()) {
                         backupManagerService.recordInitPendingLocked(true, transportName);
                     }
                     // do this via another alarm to make sure of the wakelock states
                     long delay = transport.requestBackupTime();
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Init failed on " + transportName + " resched in " + delay);
+                    Slog.w(TAG, "Init failed on " + transportName + " resched in " + delay);
                     backupManagerService.getAlarmManager().set(AlarmManager.RTC_WAKEUP,
                             System.currentTimeMillis() + delay,
                             backupManagerService.getRunInitIntent());
                 }
             }
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "Unexpected error performing init", e);
+            Slog.e(TAG, "Unexpected error performing init", e);
         } finally {
             // Done; release the wakelock
             backupManagerService.getWakelock().release();
diff --git a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
index 24f225a..e92b8be 100644
--- a/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
+++ b/services/backup/java/com/android/server/backup/internal/ProvisionedObserver.java
@@ -16,6 +16,9 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.database.ContentObserver;
 import android.os.Handler;
 import android.util.Slog;
@@ -38,8 +41,8 @@
         final boolean isProvisioned = backupManagerService.deviceIsProvisioned();
         // latch: never unprovision
         backupManagerService.setProvisioned(wasProvisioned || isProvisioned);
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.d(RefactoredBackupManagerService.TAG, "Provisioning change: was=" + wasProvisioned
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
                     + " is=" + isProvisioned + " now=" + backupManagerService.isProvisioned());
         }
 
@@ -47,9 +50,8 @@
             if (backupManagerService.isProvisioned() && !wasProvisioned
                     && backupManagerService.isEnabled()) {
                 // we're now good to go, so start the backup alarms
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG,
-                            "Now provisioned, so starting backups");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Now provisioned, so starting backups");
                 }
                 KeyValueBackupJob.schedule(backupManagerService.getContext());
                 backupManagerService.scheduleNextFullBackupJob(0);
diff --git a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
index 2372a19..f1fa7eb 100644
--- a/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
+++ b/services/backup/java/com/android/server/backup/internal/RunBackupReceiver.java
@@ -16,6 +16,10 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_BACKUP_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_BACKUP;
 
 import android.app.PendingIntent;
@@ -36,21 +40,20 @@
     }
 
     public void onReceive(Context context, Intent intent) {
-        if (RefactoredBackupManagerService.RUN_BACKUP_ACTION.equals(intent.getAction())) {
+        if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
             synchronized (backupManagerService.getQueueLock()) {
                 if (backupManagerService.getPendingInits().size() > 0) {
                     // If there are pending init operations, we process those
                     // and then settle into the usual periodic backup schedule.
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                        Slog.v(RefactoredBackupManagerService.TAG,
-                                "Init pending at scheduled backup");
+                    if (MORE_DEBUG) {
+                        Slog.v(TAG, "Init pending at scheduled backup");
                     }
                     try {
                         backupManagerService.getAlarmManager().cancel(
                                 backupManagerService.getRunInitIntent());
                         backupManagerService.getRunInitIntent().send();
                     } catch (PendingIntent.CanceledException ce) {
-                        Slog.e(RefactoredBackupManagerService.TAG, "Run init intent cancelled");
+                        Slog.e(TAG, "Run init intent cancelled");
                         // can't really do more than bail here
                     }
                 } else {
@@ -58,8 +61,8 @@
                     // fully set up.
                     if (backupManagerService.isEnabled() && backupManagerService.isProvisioned()) {
                         if (!backupManagerService.isBackupRunning()) {
-                            if (RefactoredBackupManagerService.DEBUG) {
-                                Slog.v(RefactoredBackupManagerService.TAG, "Running a backup pass");
+                            if (DEBUG) {
+                                Slog.v(TAG, "Running a backup pass");
                             }
 
                             // Acquire the wakelock and pass it to the backup thread.  it will
@@ -71,14 +74,11 @@
                                     MSG_RUN_BACKUP);
                             backupManagerService.getBackupHandler().sendMessage(msg);
                         } else {
-                            Slog.i(RefactoredBackupManagerService.TAG,
-                                    "Backup time but one already running");
+                            Slog.i(TAG, "Backup time but one already running");
                         }
                     } else {
-                        Slog.w(
-                                RefactoredBackupManagerService.TAG,
-                                "Backup pass but e=" + backupManagerService.isEnabled() + " p="
-                                        + backupManagerService.isProvisioned());
+                        Slog.w(TAG, "Backup pass but e=" + backupManagerService.isEnabled() + " p="
+                                + backupManagerService.isProvisioned());
                     }
                 }
             }
diff --git a/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
index 6609900..1621a91 100644
--- a/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
+++ b/services/backup/java/com/android/server/backup/internal/RunInitializeReceiver.java
@@ -16,6 +16,9 @@
 
 package com.android.server.backup.internal;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.RUN_INITIALIZE_ACTION;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_INITIALIZE;
 
 import android.content.BroadcastReceiver;
@@ -35,10 +38,10 @@
     }
 
     public void onReceive(Context context, Intent intent) {
-        if (RefactoredBackupManagerService.RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
+        if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
             synchronized (backupManagerService.getQueueLock()) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.v(RefactoredBackupManagerService.TAG, "Running a device init");
+                if (DEBUG) {
+                    Slog.v(TAG, "Running a device init");
                 }
 
                 // Acquire the wakelock and pass it to the init thread.  it will
diff --git a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
index 8672721..8d8a013 100644
--- a/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
+++ b/services/backup/java/com/android/server/backup/restore/ActiveRestoreSession.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup.restore;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
 import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;
@@ -115,7 +117,7 @@
                 android.Manifest.permission.BACKUP,
                 "performRestore");
 
-        if (RefactoredBackupManagerService.DEBUG) {
+        if (DEBUG) {
             Slog.d(TAG, "restoreAll token=" + Long.toHexString(token)
                     + " observer=" + observer);
         }
@@ -157,7 +159,7 @@
 
                     long oldId = Binder.clearCallingIdentity();
                     backupManagerService.getWakelock().acquire();
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "restoreAll() kicking off");
                     }
                     Message msg = backupManagerService.getBackupHandler().obtainMessage(
@@ -182,7 +184,7 @@
                 android.Manifest.permission.BACKUP,
                 "performRestore");
 
-        if (RefactoredBackupManagerService.DEBUG) {
+        if (DEBUG) {
             StringBuilder b = new StringBuilder(128);
             b.append("restoreSome token=");
             b.append(Long.toHexString(token));
@@ -250,7 +252,7 @@
 
                     long oldId = Binder.clearCallingIdentity();
                     backupManagerService.getWakelock().acquire();
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                    if (MORE_DEBUG) {
                         Slog.d(TAG, "restoreSome() of " + packages.length + " packages");
                     }
                     Message msg = backupManagerService.getBackupHandler().obtainMessage(
@@ -270,7 +272,7 @@
 
     public synchronized int restorePackage(String packageName, IRestoreObserver observer,
             IBackupManagerMonitor monitor) {
-        if (RefactoredBackupManagerService.DEBUG) {
+        if (DEBUG) {
             Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer
                     + "monitor=" + monitor);
         }
@@ -318,7 +320,7 @@
             // Check whether there is data for it in the current dataset, falling back
             // to the ancestral dataset if not.
             long token = backupManagerService.getAvailableRestoreToken(packageName);
-            if (RefactoredBackupManagerService.DEBUG) {
+            if (DEBUG) {
                 Slog.v(TAG, "restorePackage pkg=" + packageName
                         + " token=" + Long.toHexString(token));
             }
@@ -327,7 +329,7 @@
             // the app has never been backed up from this device -- there's nothing
             // to do but return failure.
             if (token == 0) {
-                if (RefactoredBackupManagerService.DEBUG) {
+                if (DEBUG) {
                     Slog.w(TAG, "No data available for this package; not restoring");
                 }
                 return -1;
@@ -338,8 +340,7 @@
                 dirName = mRestoreTransport.transportDirName();
             } catch (Exception e) {
                 // Transport went AWOL; fail.
-                Slog.e(TAG,
-                        "Unable to get transport dir for restorePackage: " + e.getMessage());
+                Slog.e(TAG, "Unable to get transport dir for restorePackage: " + e.getMessage());
                 return -1;
             }
 
@@ -348,7 +349,7 @@
 
             // Ready to go:  enqueue the restore request and claim success
             backupManagerService.getWakelock().acquire();
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
+            if (MORE_DEBUG) {
                 Slog.d(TAG, "restorePackage() : " + packageName);
             }
             Message msg = backupManagerService.getBackupHandler().obtainMessage(MSG_RUN_RESTORE);
@@ -387,7 +388,7 @@
     }
 
     public synchronized void endRestoreSession() {
-        if (RefactoredBackupManagerService.DEBUG) {
+        if (DEBUG) {
             Slog.d(TAG, "endRestoreSession");
         }
 
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
index 5e3664f..6353d1f 100644
--- a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -16,6 +16,10 @@
 
 package com.android.server.backup.restore;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+
 import android.util.Slog;
 
 import com.android.server.backup.BackupRestoreTask;
@@ -44,8 +48,7 @@
     void await() {
         boolean latched = false;
         try {
-            latched = mLatch.await(RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                    TimeUnit.MILLISECONDS);
+            latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
             Slog.w(TAG, "Interrupted!");
         }
@@ -58,7 +61,7 @@
 
     @Override
     public void operationComplete(long result) {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
+        if (MORE_DEBUG) {
             Slog.w(TAG, "adb onRestoreFinished() complete");
         }
         mLatch.countDown();
@@ -67,7 +70,7 @@
 
     @Override
     public void handleCancel(boolean cancelAll) {
-        if (RefactoredBackupManagerService.DEBUG) {
+        if (DEBUG) {
             Slog.w(TAG, "adb onRestoreFinished() timed out");
         }
         mLatch.countDown();
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 1d5be28..888dcd7e 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -16,6 +16,16 @@
 
 package com.android.server.backup.restore;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_SHARED_BACKUP_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
 import android.app.ApplicationThreadConstants;
@@ -52,58 +62,61 @@
  */
 public class FullRestoreEngine extends RestoreEngine {
 
-    private RefactoredBackupManagerService backupManagerService;
+    private final RefactoredBackupManagerService mBackupManagerService;
     // Task in charge of monitoring timeouts
-    BackupRestoreTask mMonitorTask;
+    private final BackupRestoreTask mMonitorTask;
+
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
 
     // Dedicated observer, if any
-    IFullBackupRestoreObserver mObserver;
+    private IFullBackupRestoreObserver mObserver;
 
-    IBackupManagerMonitor mMonitor;
+    final IBackupManagerMonitor mMonitor;
 
     // Where we're delivering the file data as we go
-    IBackupAgent mAgent;
+    private IBackupAgent mAgent;
 
     // Are we permitted to only deliver a specific package's metadata?
-    PackageInfo mOnlyPackage;
+    final PackageInfo mOnlyPackage;
 
-    boolean mAllowApks;
-    boolean mAllowObbs;
+    final boolean mAllowApks;
+    private final boolean mAllowObbs;
 
     // Which package are we currently handling data for?
-    String mAgentPackage;
+    private String mAgentPackage;
 
     // Info for working with the target app process
-    ApplicationInfo mTargetApp;
+    private ApplicationInfo mTargetApp;
 
     // Machinery for restoring OBBs
-    FullBackupObbConnection mObbConnection = null;
+    private FullBackupObbConnection mObbConnection = null;
 
     // possible handling states for a given package in the restore dataset
-    final HashMap<String, RestorePolicy> mPackagePolicies
+    private final HashMap<String, RestorePolicy> mPackagePolicies
             = new HashMap<>();
 
     // installer package names for each encountered app, derived from the manifests
-    final HashMap<String, String> mPackageInstallers = new HashMap<>();
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
 
     // Signatures for a given package found in its manifest file
-    final HashMap<String, Signature[]> mManifestSignatures
+    private final HashMap<String, Signature[]> mManifestSignatures
             = new HashMap<>();
 
     // Packages we've already wiped data on when restoring their first file
-    final HashSet<String> mClearedPackages = new HashSet<>();
+    private final HashSet<String> mClearedPackages = new HashSet<>();
 
     // How much data have we moved?
-    long mBytes;
+    private long mBytes;
 
     // Working buffer
-    byte[] mBuffer;
+    final byte[] mBuffer;
 
     // Pipes for moving data
-    ParcelFileDescriptor[] mPipes = null;
+    private ParcelFileDescriptor[] mPipes = null;
 
     // Widget blob to be restored out-of-band
-    byte[] mWidgetData = null;
+    private byte[] mWidgetData = null;
 
     final int mEphemeralOpToken;
 
@@ -111,7 +124,7 @@
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
             IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
             boolean allowObbs, int ephemeralOpToken) {
-        this.backupManagerService = backupManagerService;
+        mBackupManagerService = backupManagerService;
         mEphemeralOpToken = ephemeralOpToken;
         mMonitorTask = monitorTask;
         mObserver = observer;
@@ -134,7 +147,7 @@
     public boolean restoreOneFile(InputStream instream, boolean mustKillAgent, byte[] buffer,
             PackageInfo onlyPackage, boolean allowApks, int token, IBackupManagerMonitor monitor) {
         if (!isRunning()) {
-            Slog.w(RefactoredBackupManagerService.TAG, "Restore engine used after halting");
+            Slog.w(TAG, "Restore engine used after halting");
             return false;
         }
 
@@ -150,12 +163,12 @@
 
         FileMetadata info;
         try {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "Reading tar header for restoring file");
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Reading tar header for restoring file");
             }
             info = tarBackupReader.readTarHeaders();
             if (info != null) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     info.dump();
                 }
 
@@ -165,9 +178,7 @@
                     // one app's data but see a different app's on the wire
                     if (onlyPackage != null) {
                         if (!pkg.equals(onlyPackage.packageName)) {
-                            Slog.w(RefactoredBackupManagerService.TAG,
-                                    "Expected data for " + onlyPackage
-                                            + " but saw " + pkg);
+                            Slog.w(TAG, "Expected data for " + onlyPackage + " but saw " + pkg);
                             setResult(RestoreEngine.TRANSPORT_FAILURE);
                             setRunning(false);
                             return false;
@@ -183,9 +194,8 @@
                     // Clean up the previous agent relationship if necessary,
                     // and let the observer know we're considering a new app.
                     if (mAgent != null) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Saw new package; finalizing old one");
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
                         }
                         // Now we're really done
                         tearDownPipes();
@@ -195,19 +205,20 @@
                     }
                 }
 
-                if (info.path.equals(RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME)) {
-                    RestorePolicy appManifest = tarBackupReader.readAppManifest(
-                            backupManagerService.getPackageManager(), allowApks,
-                            mManifestSignatures, info);
-                    mPackagePolicies.put(pkg, appManifest);
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks, info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
                     mPackageInstallers.put(pkg, info.installerPackageName);
                     // We've read only the manifest content itself at this point,
                     // so consume the footer before looping around to the next
                     // input file
                     tarBackupReader.skipTarPadding(info.size);
                     mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
-                } else if (info.path.equals(
-                        RefactoredBackupManagerService.BACKUP_METADATA_FILENAME)) {
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
                     // Metadata blobs!
                     tarBackupReader.readMetadata(info);
 
@@ -234,18 +245,17 @@
                             // If we're in accept-if-apk state, then the first file we
                             // see MUST be the apk.
                             if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "APK file; installing");
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
                                 }
                                 // Try to install the app.
                                 String installerName = mPackageInstallers.get(pkg);
                                 boolean isSuccessfullyInstalled = RestoreUtils.installApk(
-                                        instream, backupManagerService.getPackageManager(),
+                                        instream, mBackupManagerService.getPackageManager(),
                                         mInstallObserver, mDeleteObserver, mManifestSignatures,
                                         mPackagePolicies, info, installerName,
-                                        bytesReadListener, backupManagerService.getDataDir()
-                                                              );
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
                                 // good to go; promote to ACCEPT
                                 mPackagePolicies.put(pkg, isSuccessfullyInstalled
                                         ? RestorePolicy.ACCEPT
@@ -265,9 +275,8 @@
 
                         case ACCEPT:
                             if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "apk present but ACCEPT");
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
                                 }
                                 // we can take the data without the apk, so we
                                 // *want* to do so.  skip the apk by declaring this
@@ -281,8 +290,7 @@
                             // Something has gone dreadfully wrong when determining
                             // the restore policy from the manifest.  Ignore the
                             // rest of this package's data.
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Invalid policy from manifest");
+                            Slog.e(TAG, "Invalid policy from manifest");
                             okay = false;
                             mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
                             break;
@@ -295,19 +303,17 @@
 
                     // If the policy is satisfied, go ahead and set up to pipe the
                     // data to the agent.
-                    if (RefactoredBackupManagerService.MORE_DEBUG && okay && mAgent != null) {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "Reusing existing agent instance");
+                    if (MORE_DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
                     }
                     if (okay && mAgent == null) {
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Need to launch agent for " + pkg);
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
                         }
 
                         try {
                             mTargetApp =
-                                    backupManagerService.getPackageManager().getApplicationInfo(
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
                                             pkg, 0);
 
                             // If we haven't sent any data to this app yet, we probably
@@ -317,29 +323,28 @@
                                 // responsible for coherently managing a full
                                 // restore.
                                 if (mTargetApp.backupAgentName == null) {
-                                    if (RefactoredBackupManagerService.DEBUG) {
-                                        Slog.d(RefactoredBackupManagerService.TAG,
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
                                                 "Clearing app data preparatory to full restore");
                                     }
-                                    backupManagerService.clearApplicationDataSynchronous(pkg);
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
                                 } else {
-                                    if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                        Slog.d(RefactoredBackupManagerService.TAG, "backup agent ("
+                                    if (MORE_DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
                                                 + mTargetApp.backupAgentName + ") => no clear");
                                     }
                                 }
                                 mClearedPackages.add(pkg);
                             } else {
-                                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "We've initialized this app already; no clear "
-                                                    + "required");
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
                                 }
                             }
 
                             // All set; now set up the IPC and launch the agent
                             setUpPipes();
-                            mAgent = backupManagerService.bindToAgentSynchronous(mTargetApp,
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
                                     ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
                             mAgentPackage = pkg;
                         } catch (IOException e) {
@@ -349,9 +354,7 @@
                         }
 
                         if (mAgent == null) {
-                            Slog.e(
-                                    RefactoredBackupManagerService.TAG,
-                                    "Unable to create agent for " + pkg);
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
                             okay = false;
                             tearDownPipes();
                             mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
@@ -361,7 +364,7 @@
                     // Sanity check: make sure we never give data to the wrong app.  This
                     // should never happen but a little paranoia here won't go amiss.
                     if (okay && !pkg.equals(mAgentPackage)) {
-                        Slog.e(RefactoredBackupManagerService.TAG, "Restoring data for " + pkg
+                        Slog.e(TAG, "Restoring data for " + pkg
                                 + " but agent is for " + mAgentPackage);
                         okay = false;
                     }
@@ -373,84 +376,74 @@
                     if (okay) {
                         boolean agentSuccess = true;
                         long toCopy = info.size;
-                        final boolean isSharedStorage = pkg.equals(
-                                RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE);
+                        final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
                         final long timeout = isSharedStorage ?
-                                RefactoredBackupManagerService.TIMEOUT_SHARED_BACKUP_INTERVAL :
-                                RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+                                TIMEOUT_SHARED_BACKUP_INTERVAL :
+                                TIMEOUT_RESTORE_INTERVAL;
                         try {
-                            backupManagerService.prepareOperationTimeout(token,
+                            mBackupManagerService.prepareOperationTimeout(token,
                                     timeout,
                                     mMonitorTask,
-                                    RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT);
+                                    OP_TYPE_RESTORE_WAIT);
 
                             if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Restoring OBB file for " + pkg
-                                                    + " : " + info.path);
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
                                 }
                                 mObbConnection.restoreObbFile(pkg, mPipes[0],
                                         info.size, info.type, info.path, info.mode,
                                         info.mtime, token,
-                                        backupManagerService.getBackupManagerBinder());
+                                        mBackupManagerService.getBackupManagerBinder());
                             } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
                                 // This is only possible during adb restore.
                                 // TODO: Refactor to clearly separate the flows.
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Restoring key-value file for " + pkg
-                                                    + " : " + info.path);
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
                                 }
                                 KeyValueAdbRestoreEngine restoreEngine =
                                         new KeyValueAdbRestoreEngine(
-                                                backupManagerService,
-                                                backupManagerService.getDataDir(), info, mPipes[0],
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
                                                 mAgent, token);
                                 new Thread(restoreEngine, "restore-key-value-runner").start();
                             } else {
-                                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Invoking agent to restore file "
-                                                    + info.path);
+                                if (MORE_DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
                                 }
                                 // fire up the app's agent listening on the socket.  If
                                 // the agent is running in the system process we can't
                                 // just invoke it asynchronously, so we provide a thread
                                 // for it here.
                                 if (mTargetApp.processName.equals("system")) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "system process agent - spinning a thread");
+                                    Slog.d(TAG, "system process agent - spinning a thread");
                                     RestoreFileRunnable runner = new RestoreFileRunnable(
-                                            backupManagerService, mAgent, info, mPipes[0], token);
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
                                     new Thread(runner, "restore-sys-runner").start();
                                 } else {
                                     mAgent.doRestoreFile(mPipes[0], info.size, info.type,
                                             info.domain, info.path, info.mode, info.mtime,
-                                            token, backupManagerService.getBackupManagerBinder());
+                                            token, mBackupManagerService.getBackupManagerBinder());
                                 }
                             }
                         } catch (IOException e) {
                             // couldn't dup the socket for a process-local restore
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Couldn't establish restore");
+                            Slog.d(TAG, "Couldn't establish restore");
                             agentSuccess = false;
                             okay = false;
                         } catch (RemoteException e) {
                             // whoops, remote entity went away.  We'll eat the content
                             // ourselves, then, and not copy it over.
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Agent crashed during full restore");
+                            Slog.e(TAG, "Agent crashed during full restore");
                             agentSuccess = false;
                             okay = false;
                         }
 
                         // Copy over the data if the agent is still good
                         if (okay) {
-                            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                Slog.v(RefactoredBackupManagerService.TAG,
-                                        "  copying to restore agent: "
-                                                + toCopy + " bytes");
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  copying to restore agent: " + toCopy + " bytes");
                             }
                             boolean pipeOkay = true;
                             FileOutputStream pipe = new FileOutputStream(
@@ -473,9 +466,8 @@
                                     try {
                                         pipe.write(buffer, 0, nRead);
                                     } catch (IOException e) {
-                                        Slog.e(RefactoredBackupManagerService.TAG,
-                                                "Failed to write to restore pipe: "
-                                                        + e.getMessage());
+                                        Slog.e(TAG, "Failed to write to restore pipe: "
+                                                + e.getMessage());
                                         pipeOkay = false;
                                     }
                                 }
@@ -487,15 +479,14 @@
 
                             // and now that we've sent it all, wait for the remote
                             // side to acknowledge receipt
-                            agentSuccess = backupManagerService.waitUntilOperationComplete(token);
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
                         }
 
                         // okay, if the remote end failed at any point, deal with
                         // it by ignoring the rest of the restore on it
                         if (!agentSuccess) {
-                            Slog.w(RefactoredBackupManagerService.TAG,
-                                    "Agent failure restoring " + pkg + "; ending restore");
-                            backupManagerService.getBackupHandler().removeMessages(
+                            Slog.w(TAG, "Agent failure restoring " + pkg + "; ending restore");
+                            mBackupManagerService.getBackupHandler().removeMessages(
                                     MSG_RESTORE_OPERATION_TIMEOUT);
                             tearDownPipes();
                             tearDownAgent(mTargetApp);
@@ -516,8 +507,8 @@
                     // dropped file, or an already-ignored package: skip to the
                     // next stream entry by reading and discarding this file.
                     if (!okay) {
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG, "[discarding file content]");
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
                         }
                         long bytesToConsume = (info.size + 511) & ~511;
                         while (bytesToConsume > 0) {
@@ -536,9 +527,8 @@
                 }
             }
         } catch (IOException e) {
-            if (RefactoredBackupManagerService.DEBUG) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "io exception on restore socket read: " + e.getMessage());
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read: " + e.getMessage());
             }
             setResult(RestoreEngine.TRANSPORT_FAILURE);
             info = null;
@@ -546,9 +536,8 @@
 
         // If we got here we're either running smoothly or we've finished
         if (info == null) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "No [more] data for this package; tearing down");
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "No [more] data for this package; tearing down");
             }
             tearDownPipes();
             setRunning(false);
@@ -559,11 +548,11 @@
         return (info != null);
     }
 
-    void setUpPipes() throws IOException {
+    private void setUpPipes() throws IOException {
         mPipes = ParcelFileDescriptor.createPipe();
     }
 
-    void tearDownPipes() {
+    private void tearDownPipes() {
         // Teardown might arise from the inline restore processing or from the asynchronous
         // timeout mechanism, and these might race.  Make sure we don't try to close and
         // null out the pipes twice.
@@ -575,16 +564,16 @@
                     mPipes[1].close();
                     mPipes[1] = null;
                 } catch (IOException e) {
-                    Slog.w(RefactoredBackupManagerService.TAG, "Couldn't close agent pipes", e);
+                    Slog.w(TAG, "Couldn't close agent pipes", e);
                 }
                 mPipes = null;
             }
         }
     }
 
-    void tearDownAgent(ApplicationInfo app) {
+    private void tearDownAgent(ApplicationInfo app) {
         if (mAgent != null) {
-            backupManagerService.tearDownAgentAndKill(app);
+            mBackupManagerService.tearDownAgentAndKill(app);
             mAgent = null;
         }
     }
@@ -595,13 +584,10 @@
         setRunning(false);
     }
 
-    final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
-    final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
-
     private static boolean isRestorableFile(FileMetadata info) {
         if (FullBackup.CACHE_TREE_TOKEN.equals(info.domain)) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG, "Dropping cache file path " + info.path);
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Dropping cache file path " + info.path);
             }
             return false;
         }
@@ -612,9 +598,8 @@
             // API.  Respect the no-backup intention and don't let the data get to
             // the app.
             if (info.path.startsWith("no_backup/")) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "Dropping no_backup file path " + info.path);
+                if (MORE_DEBUG) {
+                    Slog.i(TAG, "Dropping no_backup file path " + info.path);
                 }
                 return false;
             }
@@ -626,8 +611,8 @@
 
     private static boolean isCanonicalFilePath(String path) {
         if (path.contains("..") || path.contains("//")) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Dropping invalid path " + path);
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
             }
             return false;
         }
@@ -641,8 +626,7 @@
                 // TODO: use a more user-friendly name string
                 mObserver.onRestorePackage(name);
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full restore observer went away: restorePackage");
+                Slog.w(TAG, "full restore observer went away: restorePackage");
                 mObserver = null;
             }
         }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index 6b26561..d5c62af 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -16,6 +16,20 @@
 
 package com.android.server.backup.restore;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_FILE_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_CURRENT;
+import static com.android.server.backup.RefactoredBackupManagerService.PBKDF_FALLBACK;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
 import android.app.ApplicationThreadConstants;
@@ -32,6 +46,7 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.KeyValueAdbRestoreEngine;
 import com.android.server.backup.PackageManagerBackupAgent;
@@ -43,7 +58,6 @@
 import com.android.server.backup.utils.RestoreUtils;
 import com.android.server.backup.utils.TarBackupReader;
 
-import java.io.DataInputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -68,38 +82,44 @@
 
 public class PerformAdbRestoreTask implements Runnable {
 
-    private RefactoredBackupManagerService backupManagerService;
-    ParcelFileDescriptor mInputFile;
-    String mCurrentPassword;
-    String mDecryptPassword;
-    IFullBackupRestoreObserver mObserver;
-    AtomicBoolean mLatchObject;
-    IBackupAgent mAgent;
-    PackageManagerBackupAgent mPackageManagerBackupAgent;
-    String mAgentPackage;
-    ApplicationInfo mTargetApp;
-    FullBackupObbConnection mObbConnection = null;
-    ParcelFileDescriptor[] mPipes = null;
-    byte[] mWidgetData = null;
+    private final RefactoredBackupManagerService mBackupManagerService;
+    private final ParcelFileDescriptor mInputFile;
+    private final String mCurrentPassword;
+    private final String mDecryptPassword;
+    private final AtomicBoolean mLatchObject;
+    private final PackageManagerBackupAgent mPackageManagerBackupAgent;
+    private final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
+    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
 
-    long mBytes;
+    private IFullBackupRestoreObserver mObserver;
+    private IBackupAgent mAgent;
+    private String mAgentPackage;
+    private ApplicationInfo mTargetApp;
+    private FullBackupObbConnection mObbConnection = null;
+    private ParcelFileDescriptor[] mPipes = null;
+    private byte[] mWidgetData = null;
+
+    private long mBytes;
 
     // Runner that can be placed on a separate thread to do in-process invocation
     // of the "restore finished" API asynchronously.  Used by adb restore.
-    class RestoreFinishedRunnable implements Runnable {
+    private static class RestoreFinishedRunnable implements Runnable {
 
-        final IBackupAgent mAgent;
-        final int mToken;
+        private final IBackupAgent mAgent;
+        private final int mToken;
+        private final RefactoredBackupManagerService mBackupManagerService;
 
-        RestoreFinishedRunnable(IBackupAgent agent, int token) {
+        RestoreFinishedRunnable(IBackupAgent agent, int token,
+                RefactoredBackupManagerService backupManagerService) {
             mAgent = agent;
             mToken = token;
+            mBackupManagerService = backupManagerService;
         }
 
         @Override
         public void run() {
             try {
-                mAgent.doRestoreFinished(mToken, backupManagerService.getBackupManagerBinder());
+                mAgent.doRestoreFinished(mToken, mBackupManagerService.getBackupManagerBinder());
             } catch (RemoteException e) {
                 // never happens; this is used only for local binder calls
             }
@@ -107,23 +127,23 @@
     }
 
     // possible handling states for a given package in the restore dataset
-    final HashMap<String, RestorePolicy> mPackagePolicies
+    private final HashMap<String, RestorePolicy> mPackagePolicies
             = new HashMap<>();
 
     // installer package names for each encountered app, derived from the manifests
-    final HashMap<String, String> mPackageInstallers = new HashMap<>();
+    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
 
     // Signatures for a given package found in its manifest file
-    final HashMap<String, Signature[]> mManifestSignatures
+    private final HashMap<String, Signature[]> mManifestSignatures
             = new HashMap<>();
 
     // Packages we've already wiped data on when restoring their first file
-    final HashSet<String> mClearedPackages = new HashSet<>();
+    private final HashSet<String> mClearedPackages = new HashSet<>();
 
     public PerformAdbRestoreTask(RefactoredBackupManagerService backupManagerService,
             ParcelFileDescriptor fd, String curPassword, String decryptPassword,
             IFullBackupRestoreObserver observer, AtomicBoolean latch) {
-        this.backupManagerService = backupManagerService;
+        this.mBackupManagerService = backupManagerService;
         mInputFile = fd;
         mCurrentPassword = curPassword;
         mDecryptPassword = decryptPassword;
@@ -139,115 +159,65 @@
         // Which packages we've already wiped data on.  We prepopulate this
         // with a whitelist of packages known to be unclearable.
         mClearedPackages.add("android");
-        mClearedPackages.add(RefactoredBackupManagerService.SETTINGS_PACKAGE);
+        mClearedPackages.add(SETTINGS_PACKAGE);
     }
 
     @Override
     public void run() {
-        Slog.i(RefactoredBackupManagerService.TAG, "--- Performing full-dataset restore ---");
+        Slog.i(TAG, "--- Performing full-dataset restore ---");
         mObbConnection.establish();
         mObserver = FullBackupRestoreObserverUtils.sendStartRestore(mObserver);
 
         // Are we able to restore shared-storage data?
         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            mPackagePolicies.put(RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE,
-                    RestorePolicy.ACCEPT);
+            mPackagePolicies.put(SHARED_BACKUP_AGENT_PACKAGE, RestorePolicy.ACCEPT);
         }
 
         FileInputStream rawInStream = null;
-        DataInputStream rawDataIn = null;
         try {
-            if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Backup password mismatch; aborting");
+            if (!mBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup password mismatch; aborting");
                 }
                 return;
             }
 
             mBytes = 0;
-            byte[] buffer = new byte[32 * 1024];
+
             rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
-            rawDataIn = new DataInputStream(rawInStream);
 
-            // First, parse out the unencrypted/uncompressed header
-            boolean compressed = false;
-            InputStream preCompressStream = rawInStream;
-            final InputStream in;
-
-            boolean okay = false;
-            final int headerLen = RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC.length();
-            byte[] streamHeader = new byte[headerLen];
-            rawDataIn.readFully(streamHeader);
-            byte[] magicBytes = RefactoredBackupManagerService.BACKUP_FILE_HEADER_MAGIC.getBytes(
-                    "UTF-8");
-            if (Arrays.equals(magicBytes, streamHeader)) {
-                // okay, header looks good.  now parse out the rest of the fields.
-                String s = readHeaderLine(rawInStream);
-                final int archiveVersion = Integer.parseInt(s);
-                if (archiveVersion <= RefactoredBackupManagerService.BACKUP_FILE_VERSION) {
-                    // okay, it's a version we recognize.  if it's version 1, we may need
-                    // to try two different PBKDF2 regimes to compare checksums.
-                    final boolean pbkdf2Fallback = (archiveVersion == 1);
-
-                    s = readHeaderLine(rawInStream);
-                    compressed = (Integer.parseInt(s) != 0);
-                    s = readHeaderLine(rawInStream);
-                    if (s.equals("none")) {
-                        // no more header to parse; we're good to go
-                        okay = true;
-                    } else if (mDecryptPassword != null && mDecryptPassword.length() > 0) {
-                        preCompressStream = decodeAesHeaderAndInitialize(s, pbkdf2Fallback,
-                                rawInStream);
-                        if (preCompressStream != null) {
-                            okay = true;
-                        }
-                    } else {
-                        Slog.w(RefactoredBackupManagerService.TAG,
-                                "Archive is encrypted but no password given");
-                    }
-                } else {
-                    Slog.w(RefactoredBackupManagerService.TAG, "Wrong header version: " + s);
-                }
-            } else {
-                Slog.w(RefactoredBackupManagerService.TAG, "Didn't read the right header magic");
-            }
-
-            if (!okay) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Invalid restore data; aborting.");
+            InputStream tarInputStream = parseBackupFileHeaderAndReturnTarStream(rawInStream,
+                    mDecryptPassword);
+            if (tarInputStream == null) {
+                // There was an error reading the backup file, which is already handled and logged.
+                // Just abort.
                 return;
             }
 
-            // okay, use the right stream layer based on compression
-            in = (compressed) ? new InflaterInputStream(preCompressStream) : preCompressStream;
-
+            byte[] buffer = new byte[32 * 1024];
             boolean didRestore;
             do {
-                didRestore = restoreOneFile(in, false /* mustKillAgent */, buffer,
+                didRestore = restoreOneFile(tarInputStream, false /* mustKillAgent */, buffer,
                         null /* onlyPackage */, true /* allowApks */,
-                        backupManagerService.generateRandomIntegerToken(), null /* monitor */);
+                        mBackupManagerService.generateRandomIntegerToken(), null /* monitor */);
             } while (didRestore);
 
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG,
-                        "Done consuming input tarfile, total bytes=" + mBytes);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
             }
         } catch (IOException e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "Unable to read restore input");
+            Slog.e(TAG, "Unable to read restore input");
         } finally {
             tearDownPipes();
             tearDownAgent(mTargetApp, true);
 
             try {
-                if (rawDataIn != null) {
-                    rawDataIn.close();
-                }
                 if (rawInStream != null) {
                     rawInStream.close();
                 }
                 mInputFile.close();
             } catch (IOException e) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Close of restore data pipe threw", e);
+                Slog.w(TAG, "Close of restore data pipe threw", e);
                 /* nothing we can do about this */
             }
             synchronized (mLatchObject) {
@@ -256,12 +226,79 @@
             }
             mObbConnection.tearDown();
             mObserver = FullBackupRestoreObserverUtils.sendEndRestore(mObserver);
-            Slog.d(RefactoredBackupManagerService.TAG, "Full restore pass complete.");
-            backupManagerService.getWakelock().release();
+            Slog.d(TAG, "Full restore pass complete.");
+            mBackupManagerService.getWakelock().release();
         }
     }
 
-    String readHeaderLine(InputStream in) throws IOException {
+    private static void readFullyOrThrow(InputStream in, byte[] buffer) throws IOException {
+        int offset = 0;
+        while (offset < buffer.length) {
+            int bytesRead = in.read(buffer, offset, buffer.length - offset);
+            if (bytesRead <= 0) {
+                throw new IOException("Couldn't fully read data");
+            }
+            offset += bytesRead;
+        }
+    }
+
+    @VisibleForTesting
+    public static InputStream parseBackupFileHeaderAndReturnTarStream(
+            InputStream rawInputStream,
+            String decryptPassword)
+            throws IOException {
+        // First, parse out the unencrypted/uncompressed header
+        boolean compressed = false;
+        InputStream preCompressStream = rawInputStream;
+
+        boolean okay = false;
+        final int headerLen = BACKUP_FILE_HEADER_MAGIC.length();
+        byte[] streamHeader = new byte[headerLen];
+        readFullyOrThrow(rawInputStream, streamHeader);
+        byte[] magicBytes = BACKUP_FILE_HEADER_MAGIC.getBytes(
+                "UTF-8");
+        if (Arrays.equals(magicBytes, streamHeader)) {
+            // okay, header looks good.  now parse out the rest of the fields.
+            String s = readHeaderLine(rawInputStream);
+            final int archiveVersion = Integer.parseInt(s);
+            if (archiveVersion <= BACKUP_FILE_VERSION) {
+                // okay, it's a version we recognize.  if it's version 1, we may need
+                // to try two different PBKDF2 regimes to compare checksums.
+                final boolean pbkdf2Fallback = (archiveVersion == 1);
+
+                s = readHeaderLine(rawInputStream);
+                compressed = (Integer.parseInt(s) != 0);
+                s = readHeaderLine(rawInputStream);
+                if (s.equals("none")) {
+                    // no more header to parse; we're good to go
+                    okay = true;
+                } else if (decryptPassword != null && decryptPassword.length() > 0) {
+                    preCompressStream = decodeAesHeaderAndInitialize(
+                            decryptPassword, s, pbkdf2Fallback,
+                            rawInputStream);
+                    if (preCompressStream != null) {
+                        okay = true;
+                    }
+                } else {
+                    Slog.w(TAG, "Archive is encrypted but no password given");
+                }
+            } else {
+                Slog.w(TAG, "Wrong header version: " + s);
+            }
+        } else {
+            Slog.w(TAG, "Didn't read the right header magic");
+        }
+
+        if (!okay) {
+            Slog.w(TAG, "Invalid restore data; aborting.");
+            return null;
+        }
+
+        // okay, use the right stream layer based on compression
+        return compressed ? new InflaterInputStream(preCompressStream) : preCompressStream;
+    }
+
+    private static String readHeaderLine(InputStream in) throws IOException {
         int c;
         StringBuilder buffer = new StringBuilder(80);
         while ((c = in.read()) >= 0) {
@@ -273,7 +310,8 @@
         return buffer.toString();
     }
 
-    InputStream attemptMasterKeyDecryption(String algorithm, byte[] userSalt, byte[] ckSalt,
+    private static InputStream attemptMasterKeyDecryption(String decryptPassword, String algorithm,
+            byte[] userSalt, byte[] ckSalt,
             int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream,
             boolean doLog) {
         InputStream result = null;
@@ -281,7 +319,7 @@
         try {
             Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
             SecretKey userKey = PasswordUtils
-                    .buildPasswordKey(algorithm, mDecryptPassword, userSalt,
+                    .buildPasswordKey(algorithm, decryptPassword, userSalt,
                             rounds);
             byte[] IV = PasswordUtils.hexToByteArray(userIvHex);
             IvParameterSpec ivSpec = new IvParameterSpec(IV);
@@ -317,11 +355,11 @@
                 // Only if all of the above worked properly will 'result' be assigned
                 result = new CipherInputStream(rawInStream, c);
             } else if (doLog) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Incorrect password");
+                Slog.w(TAG, "Incorrect password");
             }
         } catch (InvalidAlgorithmParameterException e) {
             if (doLog) {
-                Slog.e(RefactoredBackupManagerService.TAG, "Needed parameter spec unavailable!", e);
+                Slog.e(TAG, "Needed parameter spec unavailable!", e);
             }
         } catch (BadPaddingException e) {
             // This case frequently occurs when the wrong password is used to decrypt
@@ -329,31 +367,32 @@
             // used in the checksum failure log in order to avoid providing additional
             // information to an attacker.
             if (doLog) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Incorrect password");
+                Slog.w(TAG, "Incorrect password");
             }
         } catch (IllegalBlockSizeException e) {
             if (doLog) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Invalid block size in master key");
+                Slog.w(TAG, "Invalid block size in master key");
             }
         } catch (NoSuchAlgorithmException e) {
             if (doLog) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Needed decryption algorithm unavailable!");
+                Slog.e(TAG, "Needed decryption algorithm unavailable!");
             }
         } catch (NoSuchPaddingException e) {
             if (doLog) {
-                Slog.e(RefactoredBackupManagerService.TAG, "Needed padding mechanism unavailable!");
+                Slog.e(TAG, "Needed padding mechanism unavailable!");
             }
         } catch (InvalidKeyException e) {
             if (doLog) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Illegal password; aborting");
+                Slog.w(TAG, "Illegal password; aborting");
             }
         }
 
         return result;
     }
 
-    InputStream decodeAesHeaderAndInitialize(String encryptionName, boolean pbkdf2Fallback,
+    private static InputStream decodeAesHeaderAndInitialize(String decryptPassword,
+            String encryptionName,
+            boolean pbkdf2Fallback,
             InputStream rawInStream) {
         InputStream result = null;
         try {
@@ -371,22 +410,20 @@
                 String masterKeyBlobHex = readHeaderLine(rawInStream); // 9
 
                 // decrypt the master key blob
-                result = attemptMasterKeyDecryption(RefactoredBackupManagerService.PBKDF_CURRENT,
-                        userSalt, ckSalt,
-                        rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
+                result = attemptMasterKeyDecryption(decryptPassword, PBKDF_CURRENT,
+                        userSalt, ckSalt, rounds, userIvHex, masterKeyBlobHex, rawInStream, false);
                 if (result == null && pbkdf2Fallback) {
                     result = attemptMasterKeyDecryption(
-                            RefactoredBackupManagerService.PBKDF_FALLBACK, userSalt, ckSalt,
+                            decryptPassword, PBKDF_FALLBACK, userSalt, ckSalt,
                             rounds, userIvHex, masterKeyBlobHex, rawInStream, true);
                 }
             } else {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "Unsupported encryption method: " + encryptionName);
+                Slog.w(TAG, "Unsupported encryption method: " + encryptionName);
             }
         } catch (NumberFormatException e) {
-            Slog.w(RefactoredBackupManagerService.TAG, "Can't parse restore data header");
+            Slog.w(TAG, "Can't parse restore data header");
         } catch (IOException e) {
-            Slog.w(RefactoredBackupManagerService.TAG, "Can't read input header");
+            Slog.w(TAG, "Can't read input header");
         }
 
         return result;
@@ -406,7 +443,7 @@
         try {
             info = tarBackupReader.readTarHeaders();
             if (info != null) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (MORE_DEBUG) {
                     info.dump();
                 }
 
@@ -421,9 +458,8 @@
                     // Clean up the previous agent relationship if necessary,
                     // and let the observer know we're considering a new app.
                     if (mAgent != null) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Saw new package; finalizing old one");
+                        if (DEBUG) {
+                            Slog.d(TAG, "Saw new package; finalizing old one");
                         }
                         // Now we're really done
                         tearDownPipes();
@@ -433,19 +469,21 @@
                     }
                 }
 
-                if (info.path.equals(RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME)) {
-                    RestorePolicy appManifest = tarBackupReader.readAppManifest(
-                            backupManagerService.getPackageManager(), allowApks,
-                            mManifestSignatures, info);
-                    mPackagePolicies.put(pkg, appManifest);
+                if (info.path.equals(BACKUP_MANIFEST_FILENAME)) {
+                    Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(
+                            info);
+                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
+                            mBackupManagerService.getPackageManager(), allowApks,
+                            info, signatures);
+                    mManifestSignatures.put(info.packageName, signatures);
+                    mPackagePolicies.put(pkg, restorePolicy);
                     mPackageInstallers.put(pkg, info.installerPackageName);
                     // We've read only the manifest content itself at this point,
                     // so consume the footer before looping around to the next
                     // input file
                     tarBackupReader.skipTarPadding(info.size);
                     mObserver = FullBackupRestoreObserverUtils.sendOnRestorePackage(mObserver, pkg);
-                } else if (info.path.equals(
-                        RefactoredBackupManagerService.BACKUP_METADATA_FILENAME)) {
+                } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
                     // Metadata blobs!
                     tarBackupReader.readMetadata(info);
 
@@ -472,18 +510,17 @@
                             // If we're in accept-if-apk state, then the first file we
                             // see MUST be the apk.
                             if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "APK file; installing");
+                                if (DEBUG) {
+                                    Slog.d(TAG, "APK file; installing");
                                 }
                                 // Try to install the app.
                                 String installerName = mPackageInstallers.get(pkg);
                                 boolean isSuccessfullyInstalled = RestoreUtils.installApk(
-                                        instream, backupManagerService.getPackageManager(),
+                                        instream, mBackupManagerService.getPackageManager(),
                                         mInstallObserver, mDeleteObserver, mManifestSignatures,
                                         mPackagePolicies, info, installerName,
-                                        bytesReadListener, backupManagerService.getDataDir()
-                                                              );
+                                        bytesReadListener, mBackupManagerService.getDataDir()
+                                                                                         );
                                 // good to go; promote to ACCEPT
                                 mPackagePolicies.put(pkg, isSuccessfullyInstalled
                                         ? RestorePolicy.ACCEPT
@@ -503,9 +540,8 @@
 
                         case ACCEPT:
                             if (info.domain.equals(FullBackup.APK_TREE_TOKEN)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "apk present but ACCEPT");
+                                if (DEBUG) {
+                                    Slog.d(TAG, "apk present but ACCEPT");
                                 }
                                 // we can take the data without the apk, so we
                                 // *want* to do so.  skip the apk by declaring this
@@ -519,8 +555,7 @@
                             // Something has gone dreadfully wrong when determining
                             // the restore policy from the manifest.  Ignore the
                             // rest of this package's data.
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Invalid policy from manifest");
+                            Slog.e(TAG, "Invalid policy from manifest");
                             okay = false;
                             mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
                             break;
@@ -533,19 +568,17 @@
 
                     // If the policy is satisfied, go ahead and set up to pipe the
                     // data to the agent.
-                    if (RefactoredBackupManagerService.DEBUG && okay && mAgent != null) {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "Reusing existing agent instance");
+                    if (DEBUG && okay && mAgent != null) {
+                        Slog.i(TAG, "Reusing existing agent instance");
                     }
                     if (okay && mAgent == null) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Need to launch agent for " + pkg);
+                        if (DEBUG) {
+                            Slog.d(TAG, "Need to launch agent for " + pkg);
                         }
 
                         try {
                             mTargetApp =
-                                    backupManagerService.getPackageManager().getApplicationInfo(
+                                    mBackupManagerService.getPackageManager().getApplicationInfo(
                                             pkg, 0);
 
                             // If we haven't sent any data to this app yet, we probably
@@ -555,29 +588,28 @@
                                 // responsible for coherently managing a full
                                 // restore.
                                 if (mTargetApp.backupAgentName == null) {
-                                    if (RefactoredBackupManagerService.DEBUG) {
-                                        Slog.d(RefactoredBackupManagerService.TAG,
+                                    if (DEBUG) {
+                                        Slog.d(TAG,
                                                 "Clearing app data preparatory to full restore");
                                     }
-                                    backupManagerService.clearApplicationDataSynchronous(pkg);
+                                    mBackupManagerService.clearApplicationDataSynchronous(pkg);
                                 } else {
-                                    if (RefactoredBackupManagerService.DEBUG) {
-                                        Slog.d(RefactoredBackupManagerService.TAG, "backup agent ("
+                                    if (DEBUG) {
+                                        Slog.d(TAG, "backup agent ("
                                                 + mTargetApp.backupAgentName + ") => no clear");
                                     }
                                 }
                                 mClearedPackages.add(pkg);
                             } else {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "We've initialized this app already; no clear "
-                                                    + "required");
+                                if (DEBUG) {
+                                    Slog.d(TAG, "We've initialized this app already; no clear "
+                                            + "required");
                                 }
                             }
 
                             // All set; now set up the IPC and launch the agent
                             setUpPipes();
-                            mAgent = backupManagerService.bindToAgentSynchronous(mTargetApp,
+                            mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
                                     ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
                             mAgentPackage = pkg;
                         } catch (IOException e) {
@@ -587,9 +619,7 @@
                         }
 
                         if (mAgent == null) {
-                            Slog.e(
-                                    RefactoredBackupManagerService.TAG,
-                                    "Unable to create agent for " + pkg);
+                            Slog.e(TAG, "Unable to create agent for " + pkg);
                             okay = false;
                             tearDownPipes();
                             mPackagePolicies.put(pkg, RestorePolicy.IGNORE);
@@ -599,7 +629,7 @@
                     // Sanity check: make sure we never give data to the wrong app.  This
                     // should never happen but a little paranoia here won't go amiss.
                     if (okay && !pkg.equals(mAgentPackage)) {
-                        Slog.e(RefactoredBackupManagerService.TAG, "Restoring data for " + pkg
+                        Slog.e(TAG, "Restoring data for " + pkg
                                 + " but agent is for " + mAgentPackage);
                         okay = false;
                     }
@@ -612,67 +642,57 @@
                         boolean agentSuccess = true;
                         long toCopy = info.size;
                         try {
-                            backupManagerService
-                                    .prepareOperationTimeout(token,
-                                            RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL,
-                                            null,
-                                            RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT);
+                            mBackupManagerService.prepareOperationTimeout(
+                                    token, TIMEOUT_RESTORE_INTERVAL, null, OP_TYPE_RESTORE_WAIT);
 
                             if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Restoring OBB file for " + pkg
-                                                    + " : " + info.path);
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring OBB file for " + pkg
+                                            + " : " + info.path);
                                 }
                                 mObbConnection.restoreObbFile(pkg, mPipes[0],
                                         info.size, info.type, info.path, info.mode,
                                         info.mtime, token,
-                                        backupManagerService.getBackupManagerBinder());
+                                        mBackupManagerService.getBackupManagerBinder());
                             } else if (FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Restoring key-value file for " + pkg
-                                                    + " : " + info.path);
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Restoring key-value file for " + pkg
+                                            + " : " + info.path);
                                 }
                                 KeyValueAdbRestoreEngine restoreEngine =
                                         new KeyValueAdbRestoreEngine(
-                                                backupManagerService,
-                                                backupManagerService.getDataDir(), info, mPipes[0],
+                                                mBackupManagerService,
+                                                mBackupManagerService.getDataDir(), info, mPipes[0],
                                                 mAgent, token);
                                 new Thread(restoreEngine, "restore-key-value-runner").start();
                             } else {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "Invoking agent to restore file "
-                                                    + info.path);
+                                if (DEBUG) {
+                                    Slog.d(TAG, "Invoking agent to restore file " + info.path);
                                 }
                                 // fire up the app's agent listening on the socket.  If
                                 // the agent is running in the system process we can't
                                 // just invoke it asynchronously, so we provide a thread
                                 // for it here.
                                 if (mTargetApp.processName.equals("system")) {
-                                    Slog.d(RefactoredBackupManagerService.TAG,
-                                            "system process agent - spinning a thread");
+                                    Slog.d(TAG, "system process agent - spinning a thread");
                                     RestoreFileRunnable runner = new RestoreFileRunnable(
-                                            backupManagerService, mAgent, info, mPipes[0], token);
+                                            mBackupManagerService, mAgent, info, mPipes[0], token);
                                     new Thread(runner, "restore-sys-runner").start();
                                 } else {
                                     mAgent.doRestoreFile(mPipes[0], info.size, info.type,
                                             info.domain, info.path, info.mode, info.mtime,
-                                            token, backupManagerService.getBackupManagerBinder());
+                                            token, mBackupManagerService.getBackupManagerBinder());
                                 }
                             }
                         } catch (IOException e) {
                             // couldn't dup the socket for a process-local restore
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "Couldn't establish restore");
+                            Slog.d(TAG, "Couldn't establish restore");
                             agentSuccess = false;
                             okay = false;
                         } catch (RemoteException e) {
                             // whoops, remote entity went away.  We'll eat the content
                             // ourselves, then, and not copy it over.
-                            Slog.e(RefactoredBackupManagerService.TAG,
-                                    "Agent crashed during full restore");
+                            Slog.e(TAG, "Agent crashed during full restore");
                             agentSuccess = false;
                             okay = false;
                         }
@@ -700,8 +720,7 @@
                                     try {
                                         pipe.write(buffer, 0, nRead);
                                     } catch (IOException e) {
-                                        Slog.e(RefactoredBackupManagerService.TAG,
-                                                "Failed to write to restore pipe", e);
+                                        Slog.e(TAG, "Failed to write to restore pipe", e);
                                         pipeOkay = false;
                                     }
                                 }
@@ -713,17 +732,16 @@
 
                             // and now that we've sent it all, wait for the remote
                             // side to acknowledge receipt
-                            agentSuccess = backupManagerService.waitUntilOperationComplete(token);
+                            agentSuccess = mBackupManagerService.waitUntilOperationComplete(token);
                         }
 
                         // okay, if the remote end failed at any point, deal with
                         // it by ignoring the rest of the restore on it
                         if (!agentSuccess) {
-                            if (RefactoredBackupManagerService.DEBUG) {
-                                Slog.d(RefactoredBackupManagerService.TAG,
-                                        "Agent failure restoring " + pkg + "; now ignoring");
+                            if (DEBUG) {
+                                Slog.d(TAG, "Agent failure restoring " + pkg + "; now ignoring");
                             }
-                            backupManagerService.getBackupHandler().removeMessages(
+                            mBackupManagerService.getBackupHandler().removeMessages(
                                     MSG_RESTORE_OPERATION_TIMEOUT);
                             tearDownPipes();
                             tearDownAgent(mTargetApp, false);
@@ -735,8 +753,8 @@
                     // ignored package: skip to the next tar stream entry by
                     // reading and discarding this file.
                     if (!okay) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG, "[discarding file content]");
+                        if (DEBUG) {
+                            Slog.d(TAG, "[discarding file content]");
                         }
                         long bytesToConsume = (info.size + 511) & ~511;
                         while (bytesToConsume > 0) {
@@ -755,9 +773,8 @@
                 }
             }
         } catch (IOException e) {
-            if (RefactoredBackupManagerService.DEBUG) {
-                Slog.w(RefactoredBackupManagerService.TAG, "io exception on restore socket read",
-                        e);
+            if (DEBUG) {
+                Slog.w(TAG, "io exception on restore socket read", e);
             }
             // treat as EOF
             info = null;
@@ -768,8 +785,8 @@
 
     private static boolean isCanonicalFilePath(String path) {
         if (path.contains("..") || path.contains("//")) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Dropping invalid path " + path);
+            if (MORE_DEBUG) {
+                Slog.w(TAG, "Dropping invalid path " + path);
             }
             return false;
         }
@@ -777,11 +794,11 @@
         return true;
     }
 
-    void setUpPipes() throws IOException {
+    private void setUpPipes() throws IOException {
         mPipes = ParcelFileDescriptor.createPipe();
     }
 
-    void tearDownPipes() {
+    private void tearDownPipes() {
         if (mPipes != null) {
             try {
                 mPipes[0].close();
@@ -789,49 +806,43 @@
                 mPipes[1].close();
                 mPipes[1] = null;
             } catch (IOException e) {
-                Slog.w(RefactoredBackupManagerService.TAG, "Couldn't close agent pipes", e);
+                Slog.w(TAG, "Couldn't close agent pipes", e);
             }
             mPipes = null;
         }
     }
 
-    void tearDownAgent(ApplicationInfo app, boolean doRestoreFinished) {
+    private void tearDownAgent(ApplicationInfo app, boolean doRestoreFinished) {
         if (mAgent != null) {
             try {
                 // In the adb restore case, we do restore-finished here
                 if (doRestoreFinished) {
-                    final int token = backupManagerService.generateRandomIntegerToken();
+                    final int token = mBackupManagerService.generateRandomIntegerToken();
                     final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(
-                            backupManagerService, token);
-                    backupManagerService
-                            .prepareOperationTimeout(token,
-                                    RefactoredBackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL,
-                                    latch,
-                                    RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT);
+                            mBackupManagerService, token);
+                    mBackupManagerService.prepareOperationTimeout(
+                            token, TIMEOUT_FULL_BACKUP_INTERVAL, latch, OP_TYPE_RESTORE_WAIT);
                     if (mTargetApp.processName.equals("system")) {
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.d(RefactoredBackupManagerService.TAG,
-                                    "system agent - restoreFinished on thread");
+                        if (MORE_DEBUG) {
+                            Slog.d(TAG, "system agent - restoreFinished on thread");
                         }
-                        Runnable runner = new RestoreFinishedRunnable(mAgent, token);
+                        Runnable runner = new RestoreFinishedRunnable(mAgent, token,
+                                mBackupManagerService);
                         new Thread(runner, "restore-sys-finished-runner").start();
                     } else {
                         mAgent.doRestoreFinished(token,
-                                backupManagerService.getBackupManagerBinder());
+                                mBackupManagerService.getBackupManagerBinder());
                     }
 
                     latch.await();
                 }
 
-                backupManagerService.tearDownAgentAndKill(app);
+                mBackupManagerService.tearDownAgentAndKill(app);
             } catch (RemoteException e) {
-                Slog.d(RefactoredBackupManagerService.TAG, "Lost app trying to shut down");
+                Slog.d(TAG, "Lost app trying to shut down");
             }
             mAgent = null;
         }
     }
 
-    final RestoreInstallObserver mInstallObserver = new RestoreInstallObserver();
-    final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
-
 }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 7b025f4..21d5dc2 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -16,6 +16,16 @@
 
 package com.android.server.backup.restore;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.KEY_WIDGET_STATE;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT;
+import static com.android.server.backup.RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+import static com.android.server.backup.RefactoredBackupManagerService.SETTINGS_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+import static com.android.server.backup.RefactoredBackupManagerService
+        .TIMEOUT_RESTORE_FINISHED_INTERVAL;
+import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
@@ -174,9 +184,8 @@
                         PackageManagerBackupAgent.getStorableApplications(
                                 backupManagerService.getPackageManager());
                 filterSet = packagesToNames(apps);
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "Full restore; asking about " + filterSet.length + " apps");
+                if (DEBUG) {
+                    Slog.i(TAG, "Full restore; asking about " + filterSet.length + " apps");
                 }
             }
 
@@ -195,7 +204,7 @@
                         hasSystem = true;
                         continue;
                     }
-                    if (RefactoredBackupManagerService.SETTINGS_PACKAGE.equals(info.packageName)) {
+                    if (SETTINGS_PACKAGE.equals(info.packageName)) {
                         hasSettings = true;
                         continue;
                     }
@@ -219,18 +228,17 @@
             if (hasSettings) {
                 try {
                     mAcceptSet.add(backupManagerService.getPackageManager().getPackageInfo(
-                            RefactoredBackupManagerService.SETTINGS_PACKAGE, 0));
+                            SETTINGS_PACKAGE, 0));
                 } catch (NameNotFoundException e) {
                     // this one is always valid too
                 }
             }
         }
 
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.v(RefactoredBackupManagerService.TAG,
-                    "Restore; accept set size is " + mAcceptSet.size());
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "Restore; accept set size is " + mAcceptSet.size());
             for (PackageInfo info : mAcceptSet) {
-                Slog.v(RefactoredBackupManagerService.TAG, "   " + info.packageName);
+                Slog.v(TAG, "   " + info.packageName);
             }
         }
     }
@@ -247,8 +255,8 @@
     // Execute one tick of whatever state machine the task implements
     @Override
     public void execute() {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.v(RefactoredBackupManagerService.TAG, "*** Executing restore step " + mState);
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "*** Executing restore step " + mState);
         }
         switch (mState) {
             case INITIAL:
@@ -275,7 +283,7 @@
                 if (!mFinished) {
                     finalizeRestore();
                 } else {
-                    Slog.e(RefactoredBackupManagerService.TAG, "Duplicate finish");
+                    Slog.e(TAG, "Duplicate finish");
                 }
                 mFinished = true;
                 break;
@@ -340,14 +348,13 @@
 
             // Fetch the current metadata from the dataset first
             PackageInfo pmPackage = new PackageInfo();
-            pmPackage.packageName = RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+            pmPackage.packageName = PACKAGE_MANAGER_SENTINEL;
             mAcceptSet.add(0, pmPackage);
 
             PackageInfo[] packages = mAcceptSet.toArray(new PackageInfo[0]);
             mStatus = mTransport.startRestore(mToken, packages);
             if (mStatus != BackupTransport.TRANSPORT_OK) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Transport error " + mStatus + "; no restore possible");
+                Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
                 mStatus = BackupTransport.TRANSPORT_ERROR;
                 executeNextState(UnifiedRestoreState.FINAL);
                 return;
@@ -355,8 +362,7 @@
 
             RestoreDescription desc = mTransport.nextRestorePackage();
             if (desc == null) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "No restore metadata available; halting");
+                Slog.e(TAG, "No restore metadata available; halting");
                 mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                         BackupManagerMonitor.LOG_EVENT_ID_NO_RESTORE_METADATA_AVAILABLE,
                         mCurrentPackage,
@@ -365,9 +371,9 @@
                 executeNextState(UnifiedRestoreState.FINAL);
                 return;
             }
-            if (!RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL.equals(
+            if (!PACKAGE_MANAGER_SENTINEL.equals(
                     desc.getPackageName())) {
-                Slog.e(RefactoredBackupManagerService.TAG, "Required package metadata but got "
+                Slog.e(TAG, "Required package metadata but got "
                         + desc.getPackageName());
                 mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                         BackupManagerMonitor.LOG_EVENT_ID_NO_PM_METADATA_RECEIVED,
@@ -380,12 +386,12 @@
 
             // Pull the Package Manager metadata from the restore set first
             mCurrentPackage = new PackageInfo();
-            mCurrentPackage.packageName = RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+            mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
             mPmAgent = new PackageManagerBackupAgent(backupManagerService.getPackageManager(),
                     null);
             mAgent = IBackupAgent.Stub.asInterface(mPmAgent.onBind());
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "initiating restore for PMBA");
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "initiating restore for PMBA");
             }
             initiateOneRestore(mCurrentPackage, 0);
             // The PM agent called operationComplete() already, because our invocation
@@ -402,14 +408,13 @@
             // signature/version verification etc, so we simply do not proceed with
             // the restore operation.
             if (!mPmAgent.hasMetadata()) {
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "PM agent has no metadata, so not restoring");
+                Slog.e(TAG, "PM agent has no metadata, so not restoring");
                 mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                         BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA,
                         mCurrentPackage,
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
-                        RefactoredBackupManagerService.PACKAGE_MANAGER_SENTINEL,
+                        PACKAGE_MANAGER_SENTINEL,
                         "Package manager restore metadata missing");
                 mStatus = BackupTransport.TRANSPORT_ERROR;
                 backupManagerService.getBackupHandler().removeMessages(
@@ -423,8 +428,7 @@
 
         } catch (Exception e) {
             // If we lost the transport at any time, halt
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Unable to contact transport for restore: " + e.getMessage());
+            Slog.e(TAG, "Unable to contact transport for restore: " + e.getMessage());
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                     BackupManagerMonitor.LOG_EVENT_ID_LOST_TRANSPORT,
                     null,
@@ -446,15 +450,14 @@
             final String pkgName = (mRestoreDescription != null)
                     ? mRestoreDescription.getPackageName() : null;
             if (pkgName == null) {
-                Slog.e(RefactoredBackupManagerService.TAG, "Failure getting next package name");
+                Slog.e(TAG, "Failure getting next package name");
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 nextState = UnifiedRestoreState.FINAL;
                 return;
             } else if (mRestoreDescription == RestoreDescription.NO_MORE_PACKAGES) {
                 // Yay we've reached the end cleanly
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.v(RefactoredBackupManagerService.TAG,
-                            "No more packages; finishing restore");
+                if (DEBUG) {
+                    Slog.v(TAG, "No more packages; finishing restore");
                 }
                 int millis = (int) (SystemClock.elapsedRealtime() - mStartRealtime);
                 EventLog.writeEvent(EventLogTags.RESTORE_SUCCESS, mCount, millis);
@@ -462,15 +465,14 @@
                 return;
             }
 
-            if (RefactoredBackupManagerService.DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "Next restore package: " + mRestoreDescription);
+            if (DEBUG) {
+                Slog.i(TAG, "Next restore package: " + mRestoreDescription);
             }
             sendOnRestorePackage(pkgName);
 
             Metadata metaInfo = mPmAgent.getRestoredMetadata(pkgName);
             if (metaInfo == null) {
-                Slog.e(RefactoredBackupManagerService.TAG, "No metadata for " + pkgName);
+                Slog.e(TAG, "No metadata for " + pkgName);
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName,
                         "Package metadata missing");
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
@@ -483,7 +485,7 @@
             } catch (NameNotFoundException e) {
                 // Whoops, we thought we could restore this package but it
                 // turns out not to be present.  Skip it.
-                Slog.e(RefactoredBackupManagerService.TAG, "Package not present: " + pkgName);
+                Slog.e(TAG, "Package not present: " + pkgName);
                 mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                         BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT,
                         mCurrentPackage,
@@ -503,8 +505,7 @@
                         & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
                     String message = "Source version " + metaInfo.versionCode
                             + " > installed version " + mCurrentPackage.versionCode;
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Package " + pkgName + ": " + message);
+                    Slog.w(TAG, "Package " + pkgName + ": " + message);
                     Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                             BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
                             metaInfo.versionCode);
@@ -521,11 +522,10 @@
                     nextState = UnifiedRestoreState.RUNNING_QUEUE;
                     return;
                 } else {
-                    if (RefactoredBackupManagerService.DEBUG) {
-                        Slog.v(RefactoredBackupManagerService.TAG,
-                                "Source version " + metaInfo.versionCode
-                                        + " > installed version " + mCurrentPackage.versionCode
-                                        + " but restoreAnyVersion");
+                    if (DEBUG) {
+                        Slog.v(TAG, "Source version " + metaInfo.versionCode
+                                + " > installed version " + mCurrentPackage.versionCode
+                                + " but restoreAnyVersion");
                     }
                     Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                             BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION,
@@ -541,8 +541,8 @@
                 }
             }
 
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "Package " + pkgName
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "Package " + pkgName
                         + " restore version [" + metaInfo.versionCode
                         + "] is compatible with installed version ["
                         + mCurrentPackage.versionCode + "]");
@@ -557,14 +557,13 @@
                 nextState = UnifiedRestoreState.RESTORE_FULL;
             } else {
                 // Unknown restore type; ignore this package and move on
-                Slog.e(RefactoredBackupManagerService.TAG, "Unrecognized restore type " + type);
+                Slog.e(TAG, "Unrecognized restore type " + type);
                 nextState = UnifiedRestoreState.RUNNING_QUEUE;
                 return;
             }
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Can't get next restore target from transport; halting: "
-                            + e.getMessage());
+            Slog.e(TAG, "Can't get next restore target from transport; halting: "
+                    + e.getMessage());
             EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
             nextState = UnifiedRestoreState.FINAL;
             return;
@@ -583,8 +582,8 @@
         // only to the key/value restore API flow
         if (mCurrentPackage.applicationInfo.backupAgentName == null
                 || "".equals(mCurrentPackage.applicationInfo.backupAgentName)) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG, "Data exists for package " + packageName
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Data exists for package " + packageName
                         + " but app has no agent; skipping");
             }
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -598,8 +597,7 @@
 
         Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName);
         if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Signature mismatch restoring " + packageName);
+            Slog.w(TAG, "Signature mismatch restoring " + packageName);
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                     BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
@@ -614,8 +612,7 @@
                 mCurrentPackage.applicationInfo,
                 ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
         if (mAgent == null) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Can't find backup agent for " + packageName);
+            Slog.w(TAG, "Can't find backup agent for " + packageName);
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                     BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT, mCurrentPackage,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null);
@@ -633,8 +630,7 @@
             initiateOneRestore(mCurrentPackage, metaInfo.versionCode);
             ++mCount;
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Error when attempting restore: " + e.toString());
+            Slog.e(TAG, "Error when attempting restore: " + e.toString());
             keyValueAgentErrorCleanup();
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
         }
@@ -644,9 +640,8 @@
     void initiateOneRestore(PackageInfo app, int appVersionCode) {
         final String packageName = app.packageName;
 
-        if (RefactoredBackupManagerService.DEBUG) {
-            Slog.d(RefactoredBackupManagerService.TAG,
-                    "initiateOneRestore packageName=" + packageName);
+        if (DEBUG) {
+            Slog.d(TAG, "initiateOneRestore packageName=" + packageName);
         }
 
         // !!! TODO: get the dirs from the transport
@@ -673,8 +668,7 @@
             if (mTransport.getRestoreData(stage) != BackupTransport.TRANSPORT_OK) {
                 // Transport-level failure, so we wind everything up and
                 // terminate the restore operation.
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Error getting restore data for " + packageName);
+                Slog.e(TAG, "Error getting restore data for " + packageName);
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 stage.close();
                 downloadFile.delete();
@@ -703,11 +697,9 @@
                     final int size = in.getDataSize();
 
                     // is this a special key?
-                    if (key.equals(RefactoredBackupManagerService.KEY_WIDGET_STATE)) {
-                        if (RefactoredBackupManagerService.DEBUG) {
-                            Slog.i(
-                                    RefactoredBackupManagerService.TAG,
-                                    "Restoring widget state for " + packageName);
+                    if (key.equals(KEY_WIDGET_STATE)) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "Restoring widget state for " + packageName);
                         }
                         mWidgetData = new byte[size];
                         in.readEntityData(mWidgetData, 0, size);
@@ -738,15 +730,12 @@
             // Kick off the restore, checking for hung agents.  The timeout or
             // the operationComplete() callback will schedule the next step,
             // so we do not do that here.
-            backupManagerService
-                    .prepareOperationTimeout(mEphemeralOpToken,
-                            RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL,
-                            this, RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT);
+            backupManagerService.prepareOperationTimeout(
+                    mEphemeralOpToken, TIMEOUT_RESTORE_INTERVAL, this, OP_TYPE_RESTORE_WAIT);
             mAgent.doRestore(mBackupData, appVersionCode, mNewState,
                     mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Unable to call app for restore: " + packageName, e);
+            Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
             EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                     packageName, e.toString());
             keyValueAgentErrorCleanup();    // clears any pending timeout messages as well
@@ -771,8 +760,8 @@
         // backup looper, and the overall unified restore task resumes
         try {
             StreamFeederThread feeder = new StreamFeederThread();
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG, "Spinning threads for stream restore of "
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Spinning threads for stream restore of "
                         + mCurrentPackage.packageName);
             }
             new Thread(feeder, "unified-stream-feeder").start();
@@ -783,8 +772,7 @@
             // Unable to instantiate the feeder thread -- we need to bail on the
             // current target.  We haven't asked the transport for data yet, though,
             // so we can do that simply by going back to running the restore queue.
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Unable to construct pipes for stream restore!");
+            Slog.e(TAG, "Unable to construct pipes for stream restore!");
             executeNextState(UnifiedRestoreState.RUNNING_QUEUE);
         }
     }
@@ -794,16 +782,15 @@
         try {
             backupManagerService
                     .prepareOperationTimeout(mEphemeralOpToken,
-                            RefactoredBackupManagerService.TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
-                            RefactoredBackupManagerService.OP_TYPE_RESTORE_WAIT);
+                            TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
+                            OP_TYPE_RESTORE_WAIT);
             mAgent.doRestoreFinished(mEphemeralOpToken,
                     backupManagerService.getBackupManagerBinder());
             // If we get this far, the callback or timeout will schedule the
             // next restore state, so we're done
         } catch (Exception e) {
             final String packageName = mCurrentPackage.packageName;
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Unable to finalize restore of " + packageName);
+            Slog.e(TAG, "Unable to finalize restore of " + packageName);
             EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                     packageName, e.toString());
             keyValueAgentErrorCleanup();
@@ -863,9 +850,8 @@
                     if (result > 0) {
                         // The transport wrote this many bytes of restore data to the
                         // pipe, so pass it along to the engine.
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.v(RefactoredBackupManagerService.TAG,
-                                    "  <- transport provided chunk size " + result);
+                        if (MORE_DEBUG) {
+                            Slog.v(TAG, "  <- transport provided chunk size " + result);
                         }
                         if (result > bufferSize) {
                             bufferSize = result;
@@ -876,39 +862,35 @@
                             int n = transportIn.read(buffer, 0, toCopy);
                             engineOut.write(buffer, 0, n);
                             toCopy -= n;
-                            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                Slog.v(RefactoredBackupManagerService.TAG,
-                                        "  -> wrote " + n + " to engine, left=" + toCopy);
+                            if (MORE_DEBUG) {
+                                Slog.v(TAG, "  -> wrote " + n + " to engine, left=" + toCopy);
                             }
                         }
                     } else if (result == BackupTransport.NO_MORE_DATA) {
                         // Clean finish.  Wind up and we're done!
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.i(RefactoredBackupManagerService.TAG,
-                                    "Got clean full-restore EOF for "
-                                            + mCurrentPackage.packageName);
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Got clean full-restore EOF for "
+                                    + mCurrentPackage.packageName);
                         }
                         status = BackupTransport.TRANSPORT_OK;
                         break;
                     } else {
                         // Transport reported some sort of failure; the fall-through
                         // handling will deal properly with that.
-                        Slog.e(RefactoredBackupManagerService.TAG,
-                                "Error " + result + " streaming restore for "
-                                        + mCurrentPackage.packageName);
+                        Slog.e(TAG, "Error " + result + " streaming restore for "
+                                + mCurrentPackage.packageName);
                         EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                         status = result;
                     }
                 }
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.v(RefactoredBackupManagerService.TAG,
-                            "Done copying to engine, falling through");
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "Done copying to engine, falling through");
                 }
             } catch (IOException e) {
                 // We lost our ability to communicate via the pipes.  That's worrying
                 // but potentially recoverable; abandon this package's restore but
                 // carry on with the next restore target.
-                Slog.e(RefactoredBackupManagerService.TAG, "Unable to route data for restore");
+                Slog.e(TAG, "Unable to route data for restore");
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
                         mCurrentPackage.packageName, "I/O error on pipes");
                 status = BackupTransport.AGENT_ERROR;
@@ -916,8 +898,7 @@
                 // The transport threw; terminate the whole operation.  Closing
                 // the sockets will wake up the engine and it will then tidy up the
                 // remote end.
-                Slog.e(RefactoredBackupManagerService.TAG,
-                        "Transport failed during restore: " + e.getMessage());
+                Slog.e(TAG, "Transport failed during restore: " + e.getMessage());
                 EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                 status = BackupTransport.TRANSPORT_ERROR;
             } finally {
@@ -958,8 +939,7 @@
                     } catch (Exception e) {
                         // transport itself is dead; make sure we handle this as a
                         // fatal error
-                        Slog.e(RefactoredBackupManagerService.TAG,
-                                "Transport threw from abortFullRestore: " + e.getMessage());
+                        Slog.e(TAG, "Transport threw from abortFullRestore: " + e.getMessage());
                         status = BackupTransport.TRANSPORT_ERROR;
                     }
 
@@ -992,9 +972,8 @@
         @Override
         public void handleCancel(boolean cancelAll) {
             backupManagerService.removeOperation(mEphemeralOpToken);
-            if (RefactoredBackupManagerService.DEBUG) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "Full-data restore target timed out; shutting down");
+            if (DEBUG) {
+                Slog.w(TAG, "Full-data restore target timed out; shutting down");
             }
 
             mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
@@ -1055,14 +1034,14 @@
 
     // state FINAL : tear everything down and we're done.
     private void finalizeRestore() {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.d(RefactoredBackupManagerService.TAG, "finishing restore mObserver=" + mObserver);
+        if (MORE_DEBUG) {
+            Slog.d(TAG, "finishing restore mObserver=" + mObserver);
         }
 
         try {
             mTransport.finishRestore();
         } catch (Exception e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "Error finishing restore", e);
+            Slog.e(TAG, "Error finishing restore", e);
         }
 
         // Tell the observer we're done
@@ -1070,8 +1049,7 @@
             try {
                 mObserver.restoreFinished(mStatus);
             } catch (RemoteException e) {
-                Slog.d(RefactoredBackupManagerService.TAG,
-                        "Restore observer died at restoreFinished");
+                Slog.d(TAG, "Restore observer died at restoreFinished");
             }
         }
 
@@ -1081,8 +1059,8 @@
         // If we have a PM token, we must under all circumstances be sure to
         // handshake when we've finished.
         if (mPmToken > 0) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG, "finishing PM token " + mPmToken);
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "finishing PM token " + mPmToken);
             }
             try {
                 backupManagerService.getPackageManagerBinder().finishPackageInstall(mPmToken,
@@ -1093,7 +1071,7 @@
             // Manager, so start up the session timeout again.
             backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
                     MSG_RESTORE_SESSION_TIMEOUT,
-                    RefactoredBackupManagerService.TIMEOUT_RESTORE_INTERVAL);
+                    TIMEOUT_RESTORE_INTERVAL);
         }
 
         // Kick off any work that may be needed regarding app widget restores
@@ -1109,12 +1087,12 @@
         }
 
         // done; we can finally release the wakelock and be legitimately done.
-        Slog.i(RefactoredBackupManagerService.TAG, "Restore complete.");
+        Slog.i(TAG, "Restore complete.");
 
         synchronized (backupManagerService.getPendingRestores()) {
             if (backupManagerService.getPendingRestores().size() > 0) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG, "Starting next pending restore.");
+                if (DEBUG) {
+                    Slog.d(TAG, "Starting next pending restore.");
                 }
                 PerformUnifiedRestoreTask task = backupManagerService.getPendingRestores().remove();
                 backupManagerService.getBackupHandler().sendMessage(
@@ -1123,8 +1101,8 @@
 
             } else {
                 backupManagerService.setRestoreInProgress(false);
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.d(RefactoredBackupManagerService.TAG, "No pending restores.");
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "No pending restores.");
                 }
             }
         }
@@ -1202,10 +1180,9 @@
                                 || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0));
 
                 if (mTargetPackage == null && killAfterRestore) {
-                    if (RefactoredBackupManagerService.DEBUG) {
-                        Slog.d(RefactoredBackupManagerService.TAG,
-                                "Restore complete, killing host process of "
-                                        + mCurrentPackage.applicationInfo.processName);
+                    if (DEBUG) {
+                        Slog.d(TAG, "Restore complete, killing host process of "
+                                + mCurrentPackage.applicationInfo.processName);
                     }
                     backupManagerService.getActivityManager().killApplicationProcess(
                             mCurrentPackage.applicationInfo.processName,
@@ -1224,8 +1201,8 @@
     @Override
     public void operationComplete(long unusedResult) {
         backupManagerService.removeOperation(mEphemeralOpToken);
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(RefactoredBackupManagerService.TAG, "operationComplete() during restore: target="
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "operationComplete() during restore: target="
                     + mCurrentPackage.packageName
                     + " state=" + mState);
         }
@@ -1273,9 +1250,7 @@
             default: {
                 // Some kind of horrible semantic error; we're in an unexpected state.
                 // Back off hard and wind up.
-                Slog.e(
-                        RefactoredBackupManagerService.TAG,
-                        "Unexpected restore callback into state " + mState);
+                Slog.e(TAG, "Unexpected restore callback into state " + mState);
                 keyValueAgentErrorCleanup();
                 nextState = UnifiedRestoreState.FINAL;
                 break;
@@ -1289,8 +1264,7 @@
     @Override
     public void handleCancel(boolean cancelAll) {
         backupManagerService.removeOperation(mEphemeralOpToken);
-        Slog.e(RefactoredBackupManagerService.TAG,
-                "Timeout restoring application " + mCurrentPackage.packageName);
+        Slog.e(TAG, "Timeout restoring application " + mCurrentPackage.packageName);
         mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
                 BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_RESTORE_TIMEOUT,
                 mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
@@ -1302,8 +1276,8 @@
     }
 
     void executeNextState(UnifiedRestoreState nextState) {
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(RefactoredBackupManagerService.TAG, " => executing next step on "
+        if (MORE_DEBUG) {
+            Slog.i(TAG, " => executing next step on "
                     + this + " nextState=" + nextState);
         }
         mState = nextState;
@@ -1318,8 +1292,7 @@
             try {
                 mObserver.restoreStarting(numPackages);
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "Restore observer went away: startRestore");
+                Slog.w(TAG, "Restore observer went away: startRestore");
                 mObserver = null;
             }
         }
@@ -1331,7 +1304,7 @@
                 try {
                     mObserver.onUpdate(mCount, name);
                 } catch (RemoteException e) {
-                    Slog.d(RefactoredBackupManagerService.TAG, "Restore observer died in onUpdate");
+                    Slog.d(TAG, "Restore observer died in onUpdate");
                     mObserver = null;
                 }
             }
@@ -1343,8 +1316,7 @@
             try {
                 mObserver.restoreFinished(mStatus);
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "Restore observer went away: endRestore");
+                Slog.w(TAG, "Restore observer went away: endRestore");
                 mObserver = null;
             }
         }
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 03862c4..c033d98 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -16,14 +16,16 @@
 
 package com.android.server.backup.utils;
 
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.Signature;
 import android.os.Process;
 import android.util.Slog;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 /**
  * Utility methods wrapping operations on ApplicationInfo and PackageInfo.
  */
@@ -52,7 +54,7 @@
         }
 
         // 3. it is the special shared-storage backup package used for 'adb backup'
-        if (app.packageName.equals(RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE)) {
+        if (app.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE)) {
             return false;
         }
 
@@ -103,9 +105,8 @@
         // partition will be signed with the device's platform certificate, so on
         // different phones the same system app will have different signatures.)
         if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG,
-                        "System app " + target.packageName + " - skipping sig check");
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "System app " + target.packageName + " - skipping sig check");
             }
             return true;
         }
@@ -113,9 +114,8 @@
         // Allow unsigned apps, but not signed on one device and unsigned on the other
         // TODO(b/37977154): is this the right policy?
         Signature[] deviceSigs = target.signatures;
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.v(RefactoredBackupManagerService.TAG, "signaturesMatch(): stored=" + storedSigs
-                    + " device=" + deviceSigs);
+        if (MORE_DEBUG) {
+            Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs);
         }
         if ((storedSigs == null || storedSigs.length == 0)
                 && (deviceSigs == null || deviceSigs.length == 0)) {
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
index 3b9b692..734fa1d 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -18,6 +18,9 @@
 
 import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.BackupManagerMonitor;
 import android.app.backup.IBackupManagerMonitor;
 import android.content.pm.PackageInfo;
@@ -25,8 +28,6 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 /**
  * Utility methods to communicate with BackupManagerMonitor.
  */
@@ -62,8 +63,8 @@
                 monitor.onEvent(bundle);
                 return monitor;
             } catch (RemoteException e) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG, "backup manager monitor went away");
+                if (DEBUG) {
+                    Slog.w(TAG, "backup manager monitor went away");
                 }
             }
         }
diff --git a/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
index eb939a8..3be1e33 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupObserverUtils.java
@@ -16,13 +16,14 @@
 
 package com.android.server.backup.utils;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.BackupProgress;
 import android.app.backup.IBackupObserver;
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 /**
  * Utility methods to communicate with BackupObserver.
  */
@@ -37,9 +38,8 @@
             try {
                 observer.onUpdate(packageName, progress);
             } catch (RemoteException e) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Backup observer went away: onUpdate");
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onUpdate");
                 }
             }
         }
@@ -55,9 +55,8 @@
             try {
                 observer.onResult(packageName, status);
             } catch (RemoteException e) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Backup observer went away: onResult");
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onResult");
                 }
             }
         }
@@ -72,9 +71,8 @@
             try {
                 observer.backupFinished(status);
             } catch (RemoteException e) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Backup observer went away: backupFinished");
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: backupFinished");
                 }
             }
         }
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
index 1b511860..089109e 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupRestoreObserverUtils.java
@@ -16,12 +16,12 @@
 
 package com.android.server.backup.utils;
 
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.IFullBackupRestoreObserver;
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 /**
  * Utility methods to communicate with FullBackupRestoreObserver.
  */
@@ -38,8 +38,7 @@
             try {
                 observer.onStartRestore();
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full restore observer went away: startRestore");
+                Slog.w(TAG, "full restore observer went away: startRestore");
                 observer = null;
             }
         }
@@ -61,8 +60,7 @@
                 // TODO: use a more user-friendly name string
                 observer.onRestorePackage(name);
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full restore observer went away: restorePackage");
+                Slog.w(TAG, "full restore observer went away: restorePackage");
                 observer = null;
             }
         }
@@ -81,8 +79,7 @@
             try {
                 observer.onEndRestore();
             } catch (RemoteException e) {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "full restore observer went away: endRestore");
+                Slog.w(TAG, "full restore observer went away: endRestore");
                 observer = null;
             }
         }
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
index 4072a5e..ff92340 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup.utils;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.Signature;
@@ -23,8 +25,6 @@
 import android.os.ParcelFileDescriptor;
 import android.util.StringBuilderPrinter;
 
-import com.android.server.backup.RefactoredBackupManagerService;
-
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -88,7 +88,7 @@
         StringBuilder builder = new StringBuilder(4096);
         StringBuilderPrinter printer = new StringBuilderPrinter(builder);
 
-        printer.println(Integer.toString(RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION));
+        printer.println(Integer.toString(BACKUP_MANIFEST_VERSION));
         printer.println(pkg.packageName);
         printer.println(Integer.toString(pkg.versionCode));
         printer.println(Integer.toString(Build.VERSION.SDK_INT));
diff --git a/services/backup/java/com/android/server/backup/utils/PasswordUtils.java b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
index 5ae79e2..12fc927 100644
--- a/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/PasswordUtils.java
@@ -16,9 +16,9 @@
 
 package com.android.server.backup.utils;
 
-import android.util.Slog;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
 
-import com.android.server.backup.RefactoredBackupManagerService;
+import android.util.Slog;
 
 import java.security.Key;
 import java.security.NoSuchAlgorithmException;
@@ -127,9 +127,9 @@
                     ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE);
             return keyFactory.generateSecret(ks);
         } catch (InvalidKeySpecException e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "Invalid key spec for PBKDF2!");
+            Slog.e(TAG, "Invalid key spec for PBKDF2!");
         } catch (NoSuchAlgorithmException e) {
-            Slog.e(RefactoredBackupManagerService.TAG, "PBKDF2 unavailable!");
+            Slog.e(TAG, "PBKDF2 unavailable!");
         }
         return null;
     }
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
index c277c03..ee4201e 100644
--- a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -16,6 +16,9 @@
 
 package com.android.server.backup.utils;
 
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -25,7 +28,6 @@
 import android.util.Slog;
 
 import com.android.server.backup.FileMetadata;
-import com.android.server.backup.RefactoredBackupManagerService;
 import com.android.server.backup.restore.RestoreDeleteObserver;
 import com.android.server.backup.restore.RestoreInstallObserver;
 import com.android.server.backup.restore.RestorePolicy;
@@ -66,9 +68,8 @@
             File dataDir) {
         boolean okay = true;
 
-        if (RefactoredBackupManagerService.DEBUG) {
-            Slog.d(RefactoredBackupManagerService.TAG,
-                    "Installing from backup: " + info.packageName);
+        if (DEBUG) {
+            Slog.d(TAG, "Installing from backup: " + info.packageName);
         }
 
         // The file content is an .apk file.  Copy it out to a staging location and
@@ -112,10 +113,9 @@
                 // Okay, the install succeeded.  Make sure it was the right app.
                 boolean uninstall = false;
                 if (!installObserver.getPackageName().equals(info.packageName)) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "Restore stream claimed to include apk for "
-                                    + info.packageName + " but apk was really "
-                                    + installObserver.getPackageName());
+                    Slog.w(TAG, "Restore stream claimed to include apk for "
+                            + info.packageName + " but apk was really "
+                            + installObserver.getPackageName());
                     // delete the package we just put in place; it might be fraudulent
                     okay = false;
                     uninstall = true;
@@ -126,10 +126,9 @@
                                 PackageManager.GET_SIGNATURES);
                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
                                 == 0) {
-                            Slog.w(RefactoredBackupManagerService.TAG,
-                                    "Restore stream contains apk of package "
-                                            + info.packageName
-                                            + " but it disallows backup/restore");
+                            Slog.w(TAG, "Restore stream contains apk of package "
+                                    + info.packageName
+                                    + " but it disallows backup/restore");
                             okay = false;
                         } else {
                             // So far so good -- do the signatures match the manifest?
@@ -139,23 +138,20 @@
                                 // don't restore any of the file data.
                                 if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
                                         && (pkg.applicationInfo.backupAgentName == null)) {
-                                    Slog.w(RefactoredBackupManagerService.TAG,
-                                            "Installed app " + info.packageName
-                                                    + " has restricted uid and no agent");
+                                    Slog.w(TAG, "Installed app " + info.packageName
+                                            + " has restricted uid and no agent");
                                     okay = false;
                                 }
                             } else {
-                                Slog.w(RefactoredBackupManagerService.TAG,
-                                        "Installed app " + info.packageName
-                                                + " signatures do not match restore manifest");
+                                Slog.w(TAG, "Installed app " + info.packageName
+                                        + " signatures do not match restore manifest");
                                 okay = false;
                                 uninstall = true;
                             }
                         }
                     } catch (PackageManager.NameNotFoundException e) {
-                        Slog.w(RefactoredBackupManagerService.TAG,
-                                "Install of package " + info.packageName
-                                        + " succeeded but now not found");
+                        Slog.w(TAG, "Install of package " + info.packageName
+                                + " succeeded but now not found");
                         okay = false;
                     }
                 }
@@ -171,8 +167,7 @@
                 }
             }
         } catch (IOException e) {
-            Slog.e(RefactoredBackupManagerService.TAG,
-                    "Unable to transcribe restored apk for install");
+            Slog.e(TAG, "Unable to transcribe restored apk for install");
             okay = false;
         } finally {
             apkFile.delete();
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 12c1af2..2910ba2 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -34,6 +34,15 @@
 import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
 import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
 
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_METADATA_FILENAME;
+import static com.android.server.backup.RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;
+import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.MORE_DEBUG;
+import static com.android.server.backup.RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import static com.android.server.backup.RefactoredBackupManagerService.TAG;
+
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupManagerMonitor;
 import android.app.backup.FullBackup;
@@ -47,14 +56,12 @@
 import android.util.Slog;
 
 import com.android.server.backup.FileMetadata;
-import com.android.server.backup.RefactoredBackupManagerService;
 import com.android.server.backup.restore.RestorePolicy;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.HashMap;
 
 /**
  * Utility methods to read backup tar file.
@@ -150,23 +157,20 @@
                     case '5': {
                         info.type = BackupAgent.TYPE_DIRECTORY;
                         if (info.size != 0) {
-                            Slog.w(RefactoredBackupManagerService.TAG,
-                                    "Directory entry with nonzero size in header");
+                            Slog.w(TAG, "Directory entry with nonzero size in header");
                             info.size = 0;
                         }
                         break;
                     }
                     case 0: {
                         // presume EOF
-                        if (RefactoredBackupManagerService.MORE_DEBUG) {
-                            Slog.w(RefactoredBackupManagerService.TAG,
-                                    "Saw type=0 in tar header block, info=" + info);
+                        if (MORE_DEBUG) {
+                            Slog.w(TAG, "Saw type=0 in tar header block, info=" + info);
                         }
                         return null;
                     }
                     default: {
-                        Slog.e(RefactoredBackupManagerService.TAG,
-                                "Unknown tar entity type: " + typeChar);
+                        Slog.e(TAG, "Unknown tar entity type: " + typeChar);
                         throw new IOException("Unknown entity type " + typeChar);
                     }
                 }
@@ -178,11 +182,10 @@
                         info.path, 0, FullBackup.SHARED_PREFIX.length())) {
                     // File in shared storage.  !!! TODO: implement this.
                     info.path = info.path.substring(FullBackup.SHARED_PREFIX.length());
-                    info.packageName = RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+                    info.packageName = SHARED_BACKUP_AGENT_PACKAGE;
                     info.domain = FullBackup.SHARED_STORAGE_TOKEN;
-                    if (RefactoredBackupManagerService.DEBUG) {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "File in shared storage: " + info.path);
+                    if (DEBUG) {
+                        Slog.i(TAG, "File in shared storage: " + info.path);
                     }
                 } else if (FullBackup.APPS_PREFIX.regionMatches(0,
                         info.path, 0, FullBackup.APPS_PREFIX.length())) {
@@ -201,9 +204,8 @@
 
                     // if it's a manifest or metadata payload we're done, otherwise parse
                     // out the domain into which the file will be restored
-                    if (!info.path.equals(RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME)
-                            && !info.path.equals(
-                            RefactoredBackupManagerService.BACKUP_METADATA_FILENAME)) {
+                    if (!info.path.equals(BACKUP_MANIFEST_FILENAME) &&
+                            !info.path.equals(BACKUP_METADATA_FILENAME)) {
                         slash = info.path.indexOf('/');
                         if (slash < 0) {
                             throw new IOException("Illegal semantic path in non-manifest "
@@ -214,10 +216,9 @@
                     }
                 }
             } catch (IOException e) {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.e(RefactoredBackupManagerService.TAG,
-                            "Parse error in header: " + e.getMessage());
-                    if (RefactoredBackupManagerService.MORE_DEBUG) {
+                if (DEBUG) {
+                    Slog.e(TAG, "Parse error in header: " + e.getMessage());
+                    if (MORE_DEBUG) {
                         hexLog(block);
                     }
                 }
@@ -242,41 +243,35 @@
         if (size <= 0) {
             throw new IllegalArgumentException("size must be > 0");
         }
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(RefactoredBackupManagerService.TAG, "  ... readExactly(" + size + ") called");
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "  ... readExactly(" + size + ") called");
         }
         int soFar = 0;
         while (soFar < size) {
             int nRead = in.read(buffer, offset + soFar, size - soFar);
             if (nRead <= 0) {
-                if (RefactoredBackupManagerService.MORE_DEBUG) {
-                    Slog.w(RefactoredBackupManagerService.TAG,
-                            "- wanted exactly " + size + " but got only " + soFar);
+                if (MORE_DEBUG) {
+                    Slog.w(TAG, "- wanted exactly " + size + " but got only " + soFar);
                 }
                 break;
             }
             soFar += nRead;
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.v(RefactoredBackupManagerService.TAG,
-                        "   + got " + nRead + "; now wanting " + (size - soFar));
+            if (MORE_DEBUG) {
+                Slog.v(TAG, "   + got " + nRead + "; now wanting " + (size - soFar));
             }
         }
         return soFar;
     }
 
     /**
-     * Reads app manifest and returns a policy constant.
+     * Reads app manifest, filling version and hasApk fields in the metadata, and returns array of
+     * signatures.
      *
-     * @param packageManager - PackageManager instance.
-     * @param allowApks - allow restore set to include apks.
-     * @param manifestSignatures - parsed signatures will be put here.
      * @param info - file metadata.
-     * @return a policy constant.
+     * @return array of signatures or null, in case of an error.
      * @throws IOException in case of an error.
      */
-    public RestorePolicy readAppManifest(PackageManager packageManager,
-            boolean allowApks, HashMap<String, Signature[]> manifestSignatures,
-            FileMetadata info)
+    public Signature[] readAppManifestAndReturnSignatures(FileMetadata info)
             throws IOException {
         // Fail on suspiciously large manifest files
         if (info.size > 64 * 1024) {
@@ -284,9 +279,9 @@
         }
 
         byte[] buffer = new byte[(int) info.size];
-        if (RefactoredBackupManagerService.MORE_DEBUG) {
-            Slog.i(RefactoredBackupManagerService.TAG,
-                    "   readAppManifest() looking for " + info.size + " bytes");
+        if (MORE_DEBUG) {
+            Slog.i(TAG,
+                    "   readAppManifestAndReturnSignatures() looking for " + info.size + " bytes");
         }
         if (readExactly(mInputStream, buffer, 0, (int) info.size) == info.size) {
             mBytesReadListener.onBytesRead(info.size);
@@ -294,20 +289,19 @@
             throw new IOException("Unexpected EOF in manifest");
         }
 
-        RestorePolicy policy = RestorePolicy.IGNORE;
         String[] str = new String[1];
         int offset = 0;
 
         try {
             offset = extractLine(buffer, offset, str);
             int version = Integer.parseInt(str[0]);
-            if (version == RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION) {
+            if (version == BACKUP_MANIFEST_VERSION) {
                 offset = extractLine(buffer, offset, str);
                 String manifestPackage = str[0];
                 // TODO: handle <original-package>
                 if (manifestPackage.equals(info.packageName)) {
                     offset = extractLine(buffer, offset, str);
-                    version = Integer.parseInt(str[0]);  // app version
+                    info.version = Integer.parseInt(str[0]);  // app version
                     offset = extractLine(buffer, offset, str);
                     // This is the platform version, which we don't use, but we parse it
                     // as a safety against corruption in the manifest.
@@ -315,7 +309,7 @@
                     offset = extractLine(buffer, offset, str);
                     info.installerPackageName = (str[0].length() > 0) ? str[0] : null;
                     offset = extractLine(buffer, offset, str);
-                    boolean hasApk = str[0].equals("1");
+                    info.hasApk = str[0].equals("1");
                     offset = extractLine(buffer, offset, str);
                     int numSigs = Integer.parseInt(str[0]);
                     if (numSigs > 0) {
@@ -324,162 +318,9 @@
                             offset = extractLine(buffer, offset, str);
                             sigs[i] = new Signature(str[0]);
                         }
-                        manifestSignatures.put(info.packageName, sigs);
-
-                        // Okay, got the manifest info we need...
-                        try {
-                            PackageInfo pkgInfo = packageManager.getPackageInfo(
-                                    info.packageName, PackageManager.GET_SIGNATURES);
-                            // Fall through to IGNORE if the app explicitly disallows backup
-                            final int flags = pkgInfo.applicationInfo.flags;
-                            if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
-                                // Restore system-uid-space packages only if they have
-                                // defined a custom backup agent
-                                if ((pkgInfo.applicationInfo.uid
-                                        >= Process.FIRST_APPLICATION_UID)
-                                        || (pkgInfo.applicationInfo.backupAgentName != null)) {
-                                    // Verify signatures against any installed version; if they
-                                    // don't match, then we fall though and ignore the data.  The
-                                    // signatureMatch() method explicitly ignores the signature
-                                    // check for packages installed on the system partition, because
-                                    // such packages are signed with the platform cert instead of
-                                    // the app developer's cert, so they're different on every
-                                    // device.
-                                    if (AppBackupUtils.signaturesMatch(sigs,
-                                            pkgInfo)) {
-                                        if ((pkgInfo.applicationInfo.flags
-                                                & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
-                                            Slog.i(RefactoredBackupManagerService.TAG,
-                                                    "Package has restoreAnyVersion; taking data");
-                                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                                    mMonitor,
-                                                    LOG_EVENT_ID_RESTORE_ANY_VERSION,
-                                                    pkgInfo,
-                                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                                    null);
-                                            policy = RestorePolicy.ACCEPT;
-                                        } else if (pkgInfo.versionCode >= version) {
-                                            Slog.i(RefactoredBackupManagerService.TAG,
-                                                    "Sig + version match; taking data");
-                                            policy = RestorePolicy.ACCEPT;
-                                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                                    mMonitor,
-                                                    LOG_EVENT_ID_VERSIONS_MATCH,
-                                                    pkgInfo,
-                                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                                    null);
-                                        } else {
-                                            // The data is from a newer version of the app than
-                                            // is presently installed.  That means we can only
-                                            // use it if the matching apk is also supplied.
-                                            if (allowApks) {
-                                                Slog.i(RefactoredBackupManagerService.TAG,
-                                                        "Data version " + version
-                                                                + " is newer than installed "
-                                                                + "version "
-                                                                + pkgInfo.versionCode
-                                                                + " - requiring apk");
-                                                policy = RestorePolicy.ACCEPT_IF_APK;
-                                            } else {
-                                                Slog.i(RefactoredBackupManagerService.TAG,
-                                                        "Data requires newer version "
-                                                                + version + "; ignoring");
-                                                mMonitor = BackupManagerMonitorUtils
-                                                        .monitorEvent(mMonitor,
-                                                                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER,
-                                                                pkgInfo,
-                                                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                                                BackupManagerMonitorUtils
-                                                                        .putMonitoringExtra(
-                                                                                null,
-                                                                                EXTRA_LOG_OLD_VERSION,
-                                                                                version));
-
-                                                policy = RestorePolicy.IGNORE;
-                                            }
-                                        }
-                                    } else {
-                                        Slog.w(RefactoredBackupManagerService.TAG,
-                                                "Restore manifest signatures do not match "
-                                                        + "installed application for "
-                                                        + info.packageName);
-                                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                                mMonitor,
-                                                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH,
-                                                pkgInfo,
-                                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                                null);
-                                    }
-                                } else {
-                                    Slog.w(RefactoredBackupManagerService.TAG,
-                                            "Package " + info.packageName
-                                                    + " is system level with no agent");
-                                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
-
-
-                                            mMonitor,
-                                            LOG_EVENT_ID_SYSTEM_APP_NO_AGENT,
-                                            pkgInfo,
-                                            LOG_EVENT_CATEGORY_AGENT,
-                                            null);
-                                }
-                            } else {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.i(RefactoredBackupManagerService.TAG,
-                                            "Restore manifest from "
-                                                    + info.packageName + " but allowBackup=false");
-                                }
-                                mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                        mMonitor,
-                                        LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE,
-                                        pkgInfo,
-                                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                        null);
-                            }
-                        } catch (PackageManager.NameNotFoundException e) {
-                            // Okay, the target app isn't installed.  We can process
-                            // the restore properly only if the dataset provides the
-                            // apk file and we can successfully install it.
-                            if (allowApks) {
-                                if (RefactoredBackupManagerService.DEBUG) {
-                                    Slog.i(RefactoredBackupManagerService.TAG,
-                                            "Package " + info.packageName
-                                                    + " not installed; requiring apk in dataset");
-                                }
-                                policy = RestorePolicy.ACCEPT_IF_APK;
-                            } else {
-                                policy = RestorePolicy.IGNORE;
-                            }
-                            Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
-                                    null,
-                                    EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
-                            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
-                                    monitoringExtras,
-                                    EXTRA_LOG_POLICY_ALLOW_APKS, allowApks);
-                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                    mMonitor,
-                                    LOG_EVENT_ID_APK_NOT_INSTALLED,
-                                    null,
-                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                    monitoringExtras);
-                        }
-
-                        if (policy == RestorePolicy.ACCEPT_IF_APK && !hasApk) {
-                            Slog.i(RefactoredBackupManagerService.TAG,
-                                    "Cannot restore package " + info.packageName
-                                            + " without the matching .apk");
-                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
-                                    mMonitor,
-                                    LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK,
-                                    null,
-                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                                    BackupManagerMonitorUtils.putMonitoringExtra(null,
-                                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
-                        }
+                        return sigs;
                     } else {
-                        Slog.i(RefactoredBackupManagerService.TAG,
-                                "Missing signature on backed-up package "
-                                        + info.packageName);
+                        Slog.i(TAG, "Missing signature on backed-up package " + info.packageName);
                         mMonitor = BackupManagerMonitorUtils.monitorEvent(
                                 mMonitor,
                                 LOG_EVENT_ID_MISSING_SIGNATURE,
@@ -489,9 +330,8 @@
                                         EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
                     }
                 } else {
-                    Slog.i(RefactoredBackupManagerService.TAG,
-                            "Expected package " + info.packageName
-                                    + " but restore manifest claims " + manifestPackage);
+                    Slog.i(TAG, "Expected package " + info.packageName
+                            + " but restore manifest claims " + manifestPackage);
                     Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                             EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
                     monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
@@ -505,9 +345,8 @@
                             monitoringExtras);
                 }
             } else {
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "Unknown restore manifest version " + version
-                                + " for package " + info.packageName);
+                Slog.i(TAG, "Unknown restore manifest version " + version
+                        + " for package " + info.packageName);
                 Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                         EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
                 monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(monitoringExtras,
@@ -521,8 +360,7 @@
 
             }
         } catch (NumberFormatException e) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Corrupt restore manifest for package " + info.packageName);
+            Slog.w(TAG, "Corrupt restore manifest for package " + info.packageName);
             mMonitor = BackupManagerMonitorUtils.monitorEvent(
                     mMonitor,
                     BackupManagerMonitor.LOG_EVENT_ID_CORRUPT_MANIFEST,
@@ -531,7 +369,166 @@
                     BackupManagerMonitorUtils.putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
                             info.packageName));
         } catch (IllegalArgumentException e) {
-            Slog.w(RefactoredBackupManagerService.TAG, e.getMessage());
+            Slog.w(TAG, e.getMessage());
+        }
+
+        return null;
+    }
+
+    /**
+     * Chooses restore policy.
+     *
+     * @param packageManager - PackageManager instance.
+     * @param allowApks - allow restore set to include apks.
+     * @param info - file metadata.
+     * @param signatures - array of signatures parsed from backup file.
+     * @return a restore policy constant.
+     */
+    public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
+            boolean allowApks, FileMetadata info, Signature[] signatures) {
+        if (signatures == null) {
+            return RestorePolicy.IGNORE;
+        }
+
+        RestorePolicy policy = RestorePolicy.IGNORE;
+
+        // Okay, got the manifest info we need...
+        try {
+            PackageInfo pkgInfo = packageManager.getPackageInfo(
+                    info.packageName, PackageManager.GET_SIGNATURES);
+            // Fall through to IGNORE if the app explicitly disallows backup
+            final int flags = pkgInfo.applicationInfo.flags;
+            if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+                // Restore system-uid-space packages only if they have
+                // defined a custom backup agent
+                if ((pkgInfo.applicationInfo.uid
+                        >= Process.FIRST_APPLICATION_UID)
+                        || (pkgInfo.applicationInfo.backupAgentName != null)) {
+                    // Verify signatures against any installed version; if they
+                    // don't match, then we fall though and ignore the data.  The
+                    // signatureMatch() method explicitly ignores the signature
+                    // check for packages installed on the system partition, because
+                    // such packages are signed with the platform cert instead of
+                    // the app developer's cert, so they're different on every
+                    // device.
+                    if (AppBackupUtils.signaturesMatch(signatures, pkgInfo)) {
+                        if ((pkgInfo.applicationInfo.flags
+                                & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) {
+                            Slog.i(TAG, "Package has restoreAnyVersion; taking data");
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_RESTORE_ANY_VERSION,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                            policy = RestorePolicy.ACCEPT;
+                        } else if (pkgInfo.versionCode >= info.version) {
+                            Slog.i(TAG, "Sig + version match; taking data");
+                            policy = RestorePolicy.ACCEPT;
+                            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                    mMonitor,
+                                    LOG_EVENT_ID_VERSIONS_MATCH,
+                                    pkgInfo,
+                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                    null);
+                        } else {
+                            // The data is from a newer version of the app than
+                            // is presently installed.  That means we can only
+                            // use it if the matching apk is also supplied.
+                            if (allowApks) {
+                                Slog.i(TAG, "Data version " + info.version
+                                        + " is newer than installed "
+                                        + "version "
+                                        + pkgInfo.versionCode
+                                        + " - requiring apk");
+                                policy = RestorePolicy.ACCEPT_IF_APK;
+                            } else {
+                                Slog.i(TAG, "Data requires newer version "
+                                        + info.version + "; ignoring");
+                                mMonitor = BackupManagerMonitorUtils
+                                        .monitorEvent(mMonitor,
+                                                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER,
+                                                pkgInfo,
+                                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                                BackupManagerMonitorUtils
+                                                        .putMonitoringExtra(
+                                                                null,
+                                                                EXTRA_LOG_OLD_VERSION,
+                                                                info.version));
+
+                                policy = RestorePolicy.IGNORE;
+                            }
+                        }
+                    } else {
+                        Slog.w(TAG, "Restore manifest signatures do not match "
+                                + "installed application for "
+                                + info.packageName);
+                        mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                                mMonitor,
+                                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH,
+                                pkgInfo,
+                                LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                                null);
+                    }
+                } else {
+                    Slog.w(TAG, "Package " + info.packageName
+                            + " is system level with no agent");
+                    mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                            mMonitor,
+                            LOG_EVENT_ID_SYSTEM_APP_NO_AGENT,
+                            pkgInfo,
+                            LOG_EVENT_CATEGORY_AGENT,
+                            null);
+                }
+            } else {
+                if (DEBUG) {
+                    Slog.i(TAG,
+                            "Restore manifest from " + info.packageName + " but allowBackup=false");
+                }
+                mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                        mMonitor,
+                        LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE,
+                        pkgInfo,
+                        LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        null);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // Okay, the target app isn't installed.  We can process
+            // the restore properly only if the dataset provides the
+            // apk file and we can successfully install it.
+            if (allowApks) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Package " + info.packageName
+                            + " not installed; requiring apk in dataset");
+                }
+                policy = RestorePolicy.ACCEPT_IF_APK;
+            } else {
+                policy = RestorePolicy.IGNORE;
+            }
+            Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    null,
+                    EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
+            monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(
+                    monitoringExtras,
+                    EXTRA_LOG_POLICY_ALLOW_APKS, allowApks);
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_APK_NOT_INSTALLED,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    monitoringExtras);
+        }
+
+        if (policy == RestorePolicy.ACCEPT_IF_APK && !info.hasApk) {
+            Slog.i(TAG, "Cannot restore package " + info.packageName
+                    + " without the matching .apk");
+            mMonitor = BackupManagerMonitorUtils.monitorEvent(
+                    mMonitor,
+                    LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK,
+                    null,
+                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    BackupManagerMonitorUtils.putMonitoringExtra(null,
+                            EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName));
         }
 
         return policy;
@@ -543,9 +540,8 @@
         long partial = (size + 512) % 512;
         if (partial > 0) {
             final int needed = 512 - (int) partial;
-            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                Slog.i(RefactoredBackupManagerService.TAG,
-                        "Skipping tar padding: " + needed + " bytes");
+            if (MORE_DEBUG) {
+                Slog.i(TAG, "Skipping tar padding: " + needed + " bytes");
             }
             byte[] buffer = new byte[needed];
             if (readExactly(mInputStream, buffer, 0, needed) == needed) {
@@ -575,7 +571,7 @@
         String[] str = new String[1];
         int offset = extractLine(buffer, 0, str);
         int version = Integer.parseInt(str[0]);
-        if (version == RefactoredBackupManagerService.BACKUP_MANIFEST_VERSION) {
+        if (version == BACKUP_MANIFEST_VERSION) {
             offset = extractLine(buffer, offset, str);
             final String pkg = str[0];
             if (info.packageName.equals(pkg)) {
@@ -588,24 +584,21 @@
                     int token = in.readInt();
                     int size = in.readInt();
                     if (size > 64 * 1024) {
-                        throw new IOException("Datum "
-                                + Integer.toHexString(token)
+                        throw new IOException("Datum " + Integer.toHexString(token)
                                 + " too big; corrupt? size=" + info.size);
                     }
                     switch (token) {
-                        case RefactoredBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN: {
-                            if (RefactoredBackupManagerService.MORE_DEBUG) {
-                                Slog.i(RefactoredBackupManagerService.TAG,
-                                        "Got widget metadata for " + info.packageName);
+                        case BACKUP_WIDGET_METADATA_TOKEN: {
+                            if (MORE_DEBUG) {
+                                Slog.i(TAG, "Got widget metadata for " + info.packageName);
                             }
                             mWidgetData = new byte[size];
                             in.read(mWidgetData);
                             break;
                         }
                         default: {
-                            if (RefactoredBackupManagerService.DEBUG) {
-                                Slog.i(RefactoredBackupManagerService.TAG, "Ignoring metadata blob "
-                                        + Integer.toHexString(token)
+                            if (DEBUG) {
+                                Slog.i(TAG, "Ignoring metadata blob " + Integer.toHexString(token)
                                         + " for " + info.packageName);
                             }
                             in.skipBytes(size);
@@ -614,9 +607,9 @@
                     }
                 }
             } else {
-                Slog.w(RefactoredBackupManagerService.TAG,
-                        "Metadata mismatch: package " + info.packageName
-                                + " but widget data for " + pkg);
+                Slog.w(TAG,
+                        "Metadata mismatch: package " + info.packageName + " but widget data for "
+                                + pkg);
 
                 Bundle monitoringExtras = BackupManagerMonitorUtils.putMonitoringExtra(null,
                         EXTRA_LOG_EVENT_PACKAGE_NAME, info.packageName);
@@ -630,7 +623,7 @@
                         monitoringExtras);
             }
         } else {
-            Slog.w(RefactoredBackupManagerService.TAG, "Unsupported metadata version " + version);
+            Slog.w(TAG, "Unsupported metadata version " + version);
 
             Bundle monitoringExtras = BackupManagerMonitorUtils
                     .putMonitoringExtra(null, EXTRA_LOG_EVENT_PACKAGE_NAME,
@@ -692,9 +685,7 @@
             throws IOException {
         // We should never see a pax extended header larger than this
         if (info.size > 32 * 1024) {
-            Slog.w(RefactoredBackupManagerService.TAG,
-                    "Suspiciously large pax header size " + info.size
-                            + " - aborting");
+            Slog.w(TAG, "Suspiciously large pax header size " + info.size + " - aborting");
             throw new IOException("Sanity failure: pax header size " + info.size);
         }
 
@@ -740,8 +731,8 @@
             } else if ("size".equals(keyStr)) {
                 info.size = Long.parseLong(valStr);
             } else {
-                if (RefactoredBackupManagerService.DEBUG) {
-                    Slog.i(RefactoredBackupManagerService.TAG, "Unhandled pax key: " + key);
+                if (DEBUG) {
+                    Slog.i(TAG, "Unhandled pax key: " + key);
                 }
             }
 
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 42ea713..20a699b 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -13,7 +13,6 @@
     ../../../../system/netd/server/binder/android/net/INetd.aidl \
     ../../../../system/netd/server/binder/android/net/metrics/INetdEventListener.aidl \
     ../../../native/cmds/installd/binder/android/os/IInstalld.aidl \
-    ../../../native/services/vr/vr_window_manager/aidl/android/service/vr/IVrWindowManager.aidl \
 
 LOCAL_AIDL_INCLUDES += \
     system/netd/server/binder
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a86612e..a15992d 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -119,7 +119,8 @@
 
     private static final Intent NEXT_ALARM_CLOCK_CHANGED_INTENT =
             new Intent(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)
-                    .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+                    .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
 
     final LocalLog mLog = new LocalLog(TAG);
 
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
deleted file mode 100644
index 9629b1b..0000000
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ /dev/null
@@ -1,2260 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
-import static android.Manifest.permission.READ_CONTACTS;
-import static android.content.Context.KEYGUARD_SERVICE;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.PasswordMetrics;
-import android.app.backup.BackupManager;
-import android.app.trust.IStrongAuthTracker;
-import android.app.trust.TrustManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ServiceManager;
-import android.os.ShellCallback;
-import android.os.StrictMode;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.provider.Settings.SettingNotFoundException;
-import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.DumpUtils;
-import com.android.internal.widget.ICheckCredentialProgressCallback;
-import com.android.internal.widget.ILockSettings;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-import libcore.util.HexEncoding;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * Keeps the lock pattern/password data and related settings for each user. Used by
- * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
- * lockscreen information for secondary users.
- *
- * @hide
- */
-public class LockSettingsService extends ILockSettings.Stub {
-    private static final String TAG = "LockSettingsService";
-    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
-    private static final boolean DEBUG = false;
-
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
-
-    private final Object mSeparateChallengeLock = new Object();
-
-    private final Injector mInjector;
-    private final Context mContext;
-    private final Handler mHandler;
-    @VisibleForTesting
-    protected final LockSettingsStorage mStorage;
-    private final LockSettingsStrongAuth mStrongAuth;
-    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
-
-    private final LockPatternUtils mLockPatternUtils;
-    private final NotificationManager mNotificationManager;
-    private final UserManager mUserManager;
-    private final IActivityManager mActivityManager;
-
-    private final KeyStore mKeyStore;
-
-    private boolean mFirstCallToVold;
-    protected IGateKeeperService mGateKeeperService;
-    private SyntheticPasswordManager mSpManager;
-
-    /**
-     * The UIDs that are used for system credential storage in keystore.
-     */
-    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
-            Process.WIFI_UID, Process.VPN_UID,
-            Process.ROOT_UID };
-
-    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
-    // devices. The most basic of these is to show/hide notifications about missing features until
-    // the user unlocks the account and credential-encrypted storage is available.
-    public static final class Lifecycle extends SystemService {
-        private LockSettingsService mLockSettingsService;
-
-        public Lifecycle(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onStart() {
-            AndroidKeyStoreProvider.install();
-            mLockSettingsService = new LockSettingsService(getContext());
-            publishBinderService("lock_settings", mLockSettingsService);
-        }
-
-        @Override
-        public void onStartUser(int userHandle) {
-            mLockSettingsService.onStartUser(userHandle);
-        }
-
-        @Override
-        public void onUnlockUser(int userHandle) {
-            mLockSettingsService.onUnlockUser(userHandle);
-        }
-
-        @Override
-        public void onCleanupUser(int userHandle) {
-            mLockSettingsService.onCleanupUser(userHandle);
-        }
-    }
-
-    @VisibleForTesting
-    protected static class SynchronizedStrongAuthTracker
-            extends LockPatternUtils.StrongAuthTracker {
-        public SynchronizedStrongAuthTracker(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
-            synchronized (this) {
-                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
-            }
-        }
-
-        @Override
-        public int getStrongAuthForUser(int userId) {
-            synchronized (this) {
-                return super.getStrongAuthForUser(userId);
-            }
-        }
-
-        void register(LockSettingsStrongAuth strongAuth) {
-            strongAuth.registerStrongAuthTracker(this.mStub);
-        }
-    }
-
-    /**
-     * Tie managed profile to primary profile if it is in unified mode and not tied before.
-     *
-     * @param managedUserId Managed profile user Id
-     * @param managedUserPassword Managed profile original password (when it has separated lock).
-     *            NULL when it does not have a separated lock before.
-     */
-    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
-        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
-        // Only for managed profile
-        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
-            return;
-        }
-        // Do not tie managed profile when work challenge is enabled
-        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-            return;
-        }
-        // Do not tie managed profile to parent when it's done already
-        if (mStorage.hasChildProfileLock(managedUserId)) {
-            return;
-        }
-        // Do not tie it to parent when parent does not have a screen lock
-        final int parentId = mUserManager.getProfileParent(managedUserId).id;
-        if (!isUserSecure(parentId)) {
-            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
-            return;
-        }
-        // Do not tie when the parent has no SID (but does have a screen lock).
-        // This can only happen during an upgrade path where SID is yet to be
-        // generated when the user unlocks for the first time.
-        try {
-            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
-            return;
-        }
-        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
-        byte[] randomLockSeed = new byte[] {};
-        try {
-            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
-            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
-            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    managedUserPassword, managedUserId);
-            // We store a private credential for the managed user that's unlocked by the primary
-            // account holder's credential. As such, the user will never be prompted to enter this
-            // password directly, so we always store a password.
-            setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                    DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
-            tieProfileLockToParent(managedUserId, newPassword);
-        } catch (NoSuchAlgorithmException | RemoteException e) {
-            Slog.e(TAG, "Fail to tie managed profile", e);
-            // Nothing client can do to fix this issue, so we do not throw exception out
-        }
-    }
-
-    static class Injector {
-
-        protected Context mContext;
-
-        public Injector(Context context) {
-            mContext = context;
-        }
-
-        public Context getContext() {
-            return mContext;
-        }
-
-        public Handler getHandler() {
-            return new Handler();
-        }
-
-        public LockSettingsStorage getStorage() {
-            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
-            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                @Override
-                public void initialize(SQLiteDatabase db) {
-                    // Get the lockscreen default from a system property, if available
-                    boolean lockScreenDisable = SystemProperties.getBoolean(
-                            "ro.lockscreen.disable.default", false);
-                    if (lockScreenDisable) {
-                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
-                    }
-                }
-            });
-            return storage;
-        }
-
-        public LockSettingsStrongAuth getStrongAuth() {
-            return new LockSettingsStrongAuth(mContext);
-        }
-
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return new SynchronizedStrongAuthTracker(mContext);
-        }
-
-        public IActivityManager getActivityManager() {
-            return ActivityManager.getService();
-        }
-
-        public LockPatternUtils getLockPatternUtils() {
-            return new LockPatternUtils(mContext);
-        }
-
-        public NotificationManager getNotificationManager() {
-            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-        }
-
-        public UserManager getUserManager() {
-            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        }
-
-        public DevicePolicyManager getDevicePolicyManager() {
-            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        }
-
-        public KeyStore getKeyStore() {
-            return KeyStore.getInstance();
-        }
-
-        public IStorageManager getStorageManager() {
-            final IBinder service = ServiceManager.getService("mount");
-            if (service != null) {
-                return IStorageManager.Stub.asInterface(service);
-            }
-            return null;
-        }
-
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return new SyntheticPasswordManager(storage);
-        }
-
-        public int binderGetCallingUid() {
-            return Binder.getCallingUid();
-        }
-    }
-
-    public LockSettingsService(Context context) {
-        this(new Injector(context));
-    }
-
-    @VisibleForTesting
-    protected LockSettingsService(Injector injector) {
-        mInjector = injector;
-        mContext = injector.getContext();
-        mKeyStore = injector.getKeyStore();
-        mHandler = injector.getHandler();
-        mStrongAuth = injector.getStrongAuth();
-        mActivityManager = injector.getActivityManager();
-
-        mLockPatternUtils = injector.getLockPatternUtils();
-        mFirstCallToVold = true;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_ADDED);
-        filter.addAction(Intent.ACTION_USER_STARTING);
-        filter.addAction(Intent.ACTION_USER_REMOVED);
-        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
-                null, null);
-
-        mStorage = injector.getStorage();
-        mNotificationManager = injector.getNotificationManager();
-        mUserManager = injector.getUserManager();
-        mStrongAuthTracker = injector.getStrongAuthTracker();
-        mStrongAuthTracker.register(mStrongAuth);
-
-        mSpManager = injector.getSyntheticPasswordManager(mStorage);
-    }
-
-    /**
-     * If the account is credential-encrypted, show notification requesting the user to unlock the
-     * device.
-     */
-    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
-        final UserInfo user = mUserManager.getUserInfo(userId);
-        if (!user.isManagedProfile()) {
-            // When the user is locked, we communicate it loud-and-clear
-            // on the lockscreen; we only show a notification below for
-            // locked managed profiles.
-            return;
-        }
-
-        final UserHandle userHandle = user.getUserHandle();
-        final boolean isSecure = isUserSecure(userId);
-        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
-            UserInfo parent = mUserManager.getProfileParent(userId);
-            if (parent != null &&
-                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
-                    !mUserManager.isQuietModeEnabled(userHandle)) {
-                // Only show notifications for managed profiles once their parent
-                // user is unlocked.
-                showEncryptionNotificationForProfile(userHandle);
-            }
-        }
-    }
-
-    private void showEncryptionNotificationForProfile(UserHandle user) {
-        Resources r = mContext.getResources();
-        CharSequence title = r.getText(
-                com.android.internal.R.string.user_encrypted_title);
-        CharSequence message = r.getText(
-                com.android.internal.R.string.profile_encrypted_message);
-        CharSequence detail = r.getText(
-                com.android.internal.R.string.profile_encrypted_detail);
-
-        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
-        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
-                user.getIdentifier());
-        if (unlockIntent == null) {
-            return;
-        }
-        unlockIntent.setFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-
-        showEncryptionNotification(user, title, message, detail, intent);
-    }
-
-    private void showEncryptionNotification(UserHandle user, CharSequence title,
-            CharSequence message, CharSequence detail, PendingIntent intent) {
-        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
-
-        // Suppress all notifications on non-FBE devices for now
-        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
-
-        Notification notification =
-                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
-                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
-                        .setWhen(0)
-                        .setOngoing(true)
-                        .setTicker(title)
-                        .setColor(mContext.getColor(
-                                com.android.internal.R.color.system_notification_accent_color))
-                        .setContentTitle(title)
-                        .setContentText(message)
-                        .setSubText(detail)
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setContentIntent(intent)
-                        .build();
-        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            notification, user);
-    }
-
-    private void hideEncryptionNotification(UserHandle userHandle) {
-        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
-        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
-            userHandle);
-    }
-
-    public void onCleanupUser(int userId) {
-        hideEncryptionNotification(new UserHandle(userId));
-    }
-
-    public void onStartUser(final int userId) {
-        maybeShowEncryptionNotificationForUser(userId);
-    }
-
-    public void onUnlockUser(final int userId) {
-        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
-        // ActivityManager.unlockUser()
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                // Hide notification first, as tie managed profile lock takes time
-                hideEncryptionNotification(new UserHandle(userId));
-
-                // Now we have unlocked the parent user we should show notifications
-                // about any profiles that exist.
-                List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (int i = 0; i < profiles.size(); i++) {
-                    UserInfo profile = profiles.get(i);
-                    final boolean isSecure = isUserSecure(profile.id);
-                    if (isSecure && profile.isManagedProfile()) {
-                        UserHandle userHandle = profile.getUserHandle();
-                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
-                                !mUserManager.isQuietModeEnabled(userHandle)) {
-                            showEncryptionNotificationForProfile(userHandle);
-                        }
-                    }
-                }
-
-                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                    tieManagedProfileLockIfNecessary(userId, null);
-                }
-            }
-        });
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
-                // Notify keystore that a new user was added.
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > UserHandle.USER_SYSTEM) {
-                    removeUser(userHandle, /* unknownUser= */ true);
-                }
-                final KeyStore ks = KeyStore.getInstance();
-                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
-                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
-                ks.onUserAdded(userHandle, parentHandle);
-            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                mStorage.prefetchUser(userHandle);
-            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
-                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                if (userHandle > 0) {
-                    removeUser(userHandle, /* unknownUser= */ false);
-                }
-            }
-        }
-    };
-
-    @Override // binder interface
-    public void systemReady() {
-        migrateOldData();
-        try {
-            getGateKeeperService();
-            mSpManager.initWeaverService();
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
-        }
-        // TODO: maybe skip this for split system user mode.
-        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
-    }
-
-    private void migrateOldData() {
-        try {
-            // These Settings moved before multi-user was enabled, so we only have to do it for the
-            // root user.
-            if (getString("migrated", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                for (String validSetting : VALID_SETTINGS) {
-                    String value = Settings.Secure.getString(cr, validSetting);
-                    if (value != null) {
-                        setString(validSetting, value, 0);
-                    }
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated", "true", 0);
-                Slog.i(TAG, "Migrated lock settings to new location");
-            }
-
-            // These Settings changed after multi-user was enabled, hence need to be moved per user.
-            if (getString("migrated_user_specific", null, 0) == null) {
-                final ContentResolver cr = mContext.getContentResolver();
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int user = 0; user < users.size(); user++) {
-                    // Migrate owner info
-                    final int userId = users.get(user).id;
-                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
-                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
-                    if (!TextUtils.isEmpty(ownerInfo)) {
-                        setString(OWNER_INFO, ownerInfo, userId);
-                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
-                    }
-
-                    // Migrate owner info enabled. Note there was a bug where older platforms only
-                    // stored this value if the checkbox was toggled at least once. The code detects
-                    // this case by handling the exception.
-                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
-                    boolean enabled;
-                    try {
-                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
-                        enabled = ivalue != 0;
-                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
-                    } catch (SettingNotFoundException e) {
-                        // Setting was never stored. Store it if the string is not empty.
-                        if (!TextUtils.isEmpty(ownerInfo)) {
-                            setLong(OWNER_INFO_ENABLED, 1, userId);
-                        }
-                    }
-                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
-                }
-                // No need to move the password / pattern files. They're already in the right place.
-                setString("migrated_user_specific", "true", 0);
-                Slog.i(TAG, "Migrated per-user lock settings to new location");
-            }
-
-            // Migrates biometric weak such that the fallback mechanism becomes the primary.
-            if (getString("migrated_biometric_weak", null, 0) == null) {
-                List<UserInfo> users = mUserManager.getUsers();
-                for (int i = 0; i < users.size(); i++) {
-                    int userId = users.get(i).id;
-                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                alternateType,
-                                userId);
-                    }
-                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
-                            userId);
-                }
-                setString("migrated_biometric_weak", "true", 0);
-                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
-            }
-
-            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
-            // user was present on the system, so if we're upgrading to M and there is more than one
-            // user we disable the flag to remain consistent.
-            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
-                final List<UserInfo> users = mUserManager.getUsers();
-                final int userCount = users.size();
-                int switchableUsers = 0;
-                for (int i = 0; i < userCount; i++) {
-                    if (users.get(i).supportsSwitchTo()) {
-                        switchableUsers++;
-                    }
-                }
-
-                if (switchableUsers > 1) {
-                    for (int i = 0; i < userCount; i++) {
-                        int id = users.get(i).id;
-
-                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
-                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                        }
-                    }
-                }
-
-                setString("migrated_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen disabled flag");
-            }
-
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                final UserInfo userInfo = users.get(i);
-                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
-                    // When managed profile has a unified lock, the password quality stored has 2
-                    // possibilities only.
-                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
-                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
-                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
-                    // unified lock.
-                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
-                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                        // Only possible when it's upgraded from nyc dp3
-                        Slog.i(TAG, "Migrated tied profile lock type");
-                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
-                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
-                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
-                        // It should not happen
-                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
-                    }
-                }
-                try {
-                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
-                    java.security.KeyStore keyStore =
-                            java.security.KeyStore.getInstance("AndroidKeyStore");
-                    keyStore.load(null);
-                    if (keyStore.containsAlias(alias)) {
-                        keyStore.deleteEntry(alias);
-                    }
-                } catch (KeyStoreException | NoSuchAlgorithmException |
-                        CertificateException | IOException e) {
-                    Slog.e(TAG, "Unable to remove tied profile key", e);
-                }
-            }
-
-            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_WATCH);
-            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
-            // and device management the lockscreen must be re-enabled now for users that upgrade.
-            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
-                final int userCount = users.size();
-                for (int i = 0; i < userCount; i++) {
-                    int id = users.get(i).id;
-                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
-                }
-                setString("migrated_wear_lockscreen_disabled", "true", 0);
-                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
-            }
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to migrate old data", re);
-        }
-    }
-
-    private final void checkWritePermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
-    }
-
-    private final void checkPasswordReadPermission(int userId) {
-        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
-    }
-
-    private final void checkReadPermission(String requestedKey, int userId) {
-        final int callingUid = Binder.getCallingUid();
-
-        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + READ_CONTACTS + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-
-        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + PERMISSION + " to read "
-                        + requestedKey + " for user " + userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
-        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
-        synchronized (mSeparateChallengeLock) {
-            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
-        }
-    }
-
-    @Override
-    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
-            String managedUserPassword) throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
-            if (enabled) {
-                mStorage.removeChildProfileLock(userId);
-                removeKeystoreProfileKey(userId);
-            } else {
-                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
-            }
-        }
-    }
-
-    @Override
-    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value ? "1" : "0");
-    }
-
-    @Override
-    public void setLong(String key, long value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, Long.toString(value));
-    }
-
-    @Override
-    public void setString(String key, String value, int userId) throws RemoteException {
-        checkWritePermission(userId);
-        setStringUnchecked(key, userId, value);
-    }
-
-    private void setStringUnchecked(String key, int userId, String value) {
-        mStorage.writeKeyValue(key, value, userId);
-        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
-            BackupManager.dataChanged("com.android.providers.settings");
-        }
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ?
-                defaultValue : (value.equals("1") || value.equals("true"));
-    }
-
-    @Override
-    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        String value = getStringUnchecked(key, null, userId);
-        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
-    }
-
-    @Override
-    public String getString(String key, String defaultValue, int userId) throws RemoteException {
-        checkReadPermission(key, userId);
-        return getStringUnchecked(key, defaultValue, userId);
-    }
-
-    public String getStringUnchecked(String key, String defaultValue, int userId) {
-        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
-            long ident = Binder.clearCallingIdentity();
-            try {
-                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
-
-        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
-            key = Settings.Secure.LOCK_PATTERN_ENABLED;
-        }
-
-        return mStorage.readKeyValue(key, defaultValue, userId);
-    }
-
-    @Override
-    public boolean havePassword(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPassword(userId);
-    }
-
-    @Override
-    public boolean havePattern(int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                long handle = getSyntheticPasswordHandleLocked(userId);
-                return mSpManager.getCredentialType(handle, userId) ==
-                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            }
-        }
-        // Do we need a permissions check here?
-        return mStorage.hasPattern(userId);
-    }
-
-    private boolean isUserSecure(int userId) {
-        synchronized (mSpManager) {
-            try {
-                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                    long handle = getSyntheticPasswordHandleLocked(userId);
-                    return mSpManager.getCredentialType(handle, userId) !=
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
-                }
-            } catch (RemoteException e) {
-                // fall through
-            }
-        }
-        return mStorage.hasCredential(userId);
-    }
-
-    private void setKeystorePassword(String password, int userHandle) {
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserPasswordChanged(userHandle, password);
-    }
-
-    private void unlockKeystore(String password, int userHandle) {
-        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        final KeyStore ks = KeyStore.getInstance();
-        ks.unlock(userHandle, password);
-    }
-
-    @VisibleForTesting
-    protected String getDecryptedPasswordForTiedProfile(int userId)
-            throws KeyStoreException, UnrecoverableKeyException,
-            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
-            CertificateException, IOException {
-        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
-        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
-                storedData.length);
-        byte[] decryptionResult;
-        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-        keyStore.load(null);
-        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
-                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
-
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-
-        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
-        decryptionResult = cipher.doFinal(encryptedPassword);
-        return new String(decryptionResult, StandardCharsets.UTF_8);
-    }
-
-    private void unlockChildProfile(int profileHandle) throws RemoteException {
-        try {
-            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            if (e instanceof FileNotFoundException) {
-                Slog.i(TAG, "Child profile key not found");
-            } else {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-    }
-
-    private void unlockUser(int userId, byte[] token, byte[] secret) {
-        // TODO: make this method fully async so we can update UI with progress strings
-        final CountDownLatch latch = new CountDownLatch(1);
-        final IProgressListener listener = new IProgressListener.Stub() {
-            @Override
-            public void onStarted(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser started");
-            }
-
-            @Override
-            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser progress " + progress);
-            }
-
-            @Override
-            public void onFinished(int id, Bundle extras) throws RemoteException {
-                Log.d(TAG, "unlockUser finished");
-                latch.countDown();
-            }
-        };
-
-        try {
-            mActivityManager.unlockUser(userId, token, secret, listener);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-
-        try {
-            latch.await(15, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-        try {
-            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
-                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-                for (UserInfo pi : profiles) {
-                    // Unlock managed profile with unified lock
-                    if (pi.isManagedProfile()
-                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                            && mStorage.hasChildProfileLock(pi.id)
-                            && mUserManager.isUserRunning(pi.id)) {
-                        unlockChildProfile(pi.id);
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-            Log.d(TAG, "Failed to unlock child profile", e);
-        }
-    }
-
-    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return null;
-        }
-        Map<Integer, String> result = new ArrayMap<Integer, String>();
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (!profile.isManagedProfile()) {
-                continue;
-            }
-            final int managedUserId = profile.id;
-            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                continue;
-            }
-            try {
-                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
-            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
-                    | NoSuchPaddingException | InvalidKeyException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                // ignore
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
-     * depending on the parent user's secure state.
-     *
-     * When clearing tied work challenges, a pre-computed password table for profiles are required,
-     * since changing password for profiles requires existing password, and existing passwords can
-     * only be computed before the parent user's password is cleared.
-     *
-     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
-     * method again on profiles. However the recursion is guaranteed to terminate as this method
-     * terminates when the user is a managed profile.
-     */
-    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
-            Map<Integer, String> profilePasswordMap) throws RemoteException {
-        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-            return;
-        }
-        final boolean isSecure = isUserSecure(userId);
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        final int size = profiles.size();
-        for (int i = 0; i < size; i++) {
-            final UserInfo profile = profiles.get(i);
-            if (profile.isManagedProfile()) {
-                final int managedUserId = profile.id;
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
-                    continue;
-                }
-                if (isSecure) {
-                    tieManagedProfileLockIfNecessary(managedUserId, null);
-                } else {
-                    // We use cached work profile password computed before clearing the parent's
-                    // credential, otherwise they get lost
-                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                                profilePasswordMap.get(managedUserId), managedUserId);
-                    } else {
-                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
-                        // Supplying null here would lead to untrusted credential change
-                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
-                                managedUserId);
-                    }
-                    mStorage.removeChildProfileLock(managedUserId);
-                    removeKeystoreProfileKey(managedUserId);
-                }
-            }
-        }
-    }
-
-    private boolean isManagedProfileWithUnifiedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    private boolean isManagedProfileWithSeparatedLock(int userId) {
-        return mUserManager.getUserInfo(userId).isManagedProfile()
-                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
-    }
-
-    // This method should be called by LockPatternUtil only, all internal methods in this class
-    // should call setLockCredentialInternal.
-    @Override
-    public void setLockCredential(String credential, int type, String savedCredential, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        synchronized (mSeparateChallengeLock) {
-            setLockCredentialInternal(credential, type, savedCredential, userId);
-            setSeparateProfileChallengeEnabled(userId, true, null);
-            notifyPasswordChanged(userId);
-        }
-    }
-
-    private void setLockCredentialInternal(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        // Normalize savedCredential and credential such that empty string is always represented
-        // as null.
-        if (TextUtils.isEmpty(savedCredential)) {
-            savedCredential = null;
-        }
-        if (TextUtils.isEmpty(credential)) {
-            credential = null;
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            if (credential != null) {
-                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
-            }
-            clearUserKeyProtection(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
-            setKeystorePassword(null, userId);
-            fixateNewestUserKeyAuth(userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            notifyActivePasswordMetricsAvailable(null, userId);
-            return;
-        }
-        if (credential == null) {
-            throw new RemoteException("Null credential with mismatched credential type");
-        }
-
-        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            if (savedCredential == null) {
-                try {
-                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
-                } catch (FileNotFoundException e) {
-                    Slog.i(TAG, "Child profile key not found");
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        } else {
-            if (currentHandle.hash == null) {
-                if (savedCredential != null) {
-                    Slog.w(TAG, "Saved credential provided, but none stored");
-                }
-                savedCredential = null;
-            }
-        }
-        synchronized (mSpManager) {
-            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
-                        currentHandle.type, userId);
-                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        userId);
-                return;
-            }
-        }
-        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
-        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
-                userId);
-        if (enrolledHandle != null) {
-            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
-            mStorage.writeCredentialHash(willStore, userId);
-            // push new secret and auth token to vold
-            GateKeeperResponse gkResponse = getGateKeeperService()
-                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
-            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
-            fixateNewestUserKeyAuth(userId);
-            // Refresh the auth token
-            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-        } else {
-            throw new RemoteException("Failed to enroll " +
-                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
-                            : "pattern"));
-        }
-    }
-
-    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
-        VerifyCredentialResponse response;
-        int responseCode = gateKeeperResponse.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
-        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            byte[] token = gateKeeperResponse.getPayload();
-            if (token == null) {
-                // something's wrong if there's no payload with a challenge
-                Slog.e(TAG, "verifyChallenge response had no associated payload");
-                response = VerifyCredentialResponse.ERROR;
-            } else {
-                response = new VerifyCredentialResponse(token);
-            }
-        } else {
-            response = VerifyCredentialResponse.ERROR;
-        }
-        return response;
-    }
-
-    @VisibleForTesting
-    protected void tieProfileLockToParent(int userId, String password) {
-        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
-        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
-        byte[] encryptionResult;
-        byte[] iv;
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            try {
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .build());
-                keyStore.setEntry(
-                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
-                        new java.security.KeyStore.SecretKeyEntry(secretKey),
-                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                                .setUserAuthenticationRequired(true)
-                                .setUserAuthenticationValidityDurationSeconds(30)
-                                .build());
-                // Key imported, obtain a reference to it.
-                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
-                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
-                Cipher cipher = Cipher.getInstance(
-                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                                + KeyProperties.ENCRYPTION_PADDING_NONE);
-                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
-                encryptionResult = cipher.doFinal(randomLockSeed);
-                iv = cipher.getIV();
-            } finally {
-                // The original key can now be discarded.
-                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
-            }
-        } catch (CertificateException | UnrecoverableKeyException
-                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
-                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
-            throw new RuntimeException("Failed to encrypt key", e);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        try {
-            if (iv.length != PROFILE_KEY_IV_SIZE) {
-                throw new RuntimeException("Invalid iv length: " + iv.length);
-            }
-            outputStream.write(iv);
-            outputStream.write(encryptionResult);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to concatenate byte arrays", e);
-        }
-        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
-    }
-
-    private byte[] enrollCredential(byte[] enrolledHandle,
-            String enrolledCredential, String toEnroll, int userId)
-            throws RemoteException {
-        checkWritePermission(userId);
-        byte[] enrolledCredentialBytes = enrolledCredential == null
-                ? null
-                : enrolledCredential.getBytes();
-        byte[] toEnrollBytes = toEnroll == null
-                ? null
-                : toEnroll.getBytes();
-        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
-                enrolledCredentialBytes, toEnrollBytes);
-
-        if (response == null) {
-            return null;
-        }
-
-        byte[] hash = response.getPayload();
-        if (hash != null) {
-            setKeystorePassword(toEnroll, userId);
-        } else {
-            // Should not happen
-            Slog.e(TAG, "Throttled while enrolling a password");
-        }
-        return hash;
-    }
-
-    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
-        addUserKeyAuth(userId, null, key);
-    }
-
-    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
-        if (vcr == null) {
-            throw new RemoteException("Null response verifying a credential we just set");
-        }
-        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            throw new RemoteException("Non-OK response verifying a credential we just set: "
-                    + vcr.getResponseCode());
-        }
-        byte[] token = vcr.getPayload();
-        if (token == null) {
-            throw new RemoteException("Empty payload verifying a credential we just set");
-        }
-        addUserKeyAuth(userId, token, secretFromCredential(credential));
-    }
-
-    private void clearUserKeyProtection(int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
-        addUserKeyAuth(userId, null, null);
-    }
-
-    private static byte[] secretFromCredential(String credential) throws RemoteException {
-        try {
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            // Personalize the hash
-            byte[] personalization = "Android FBE credential hash"
-                    .getBytes(StandardCharsets.UTF_8);
-            // Pad it to the block size of the hash function
-            personalization = Arrays.copyOf(personalization, 128);
-            digest.update(personalization);
-            digest.update(credential.getBytes(StandardCharsets.UTF_8));
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
-        }
-    }
-
-    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
-            throws RemoteException {
-        final UserInfo userInfo = mUserManager.getUserInfo(userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    private void fixateNewestUserKeyAuth(int userId)
-            throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
-        final IStorageManager storageManager = mInjector.getStorageManager();
-        final long callingId = Binder.clearCallingIdentity();
-        try {
-            storageManager.fixateNewestUserKeyAuth(userId);
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
-        }
-    }
-
-    @Override
-    public void resetKeyStore(int userId) throws RemoteException {
-        checkWritePermission(userId);
-        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
-        int managedUserId = -1;
-        String managedUserDecryptedPassword = null;
-        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
-        for (UserInfo pi : profiles) {
-            // Unlock managed profile with unified lock
-            if (pi.isManagedProfile()
-                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
-                    && mStorage.hasChildProfileLock(pi.id)) {
-                try {
-                    if (managedUserId == -1) {
-                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
-                        managedUserId = pi.id;
-                    } else {
-                        // Should not happen
-                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
-                                + ", uid2:" + pi.id);
-                    }
-                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                        | NoSuchAlgorithmException | NoSuchPaddingException
-                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                        | BadPaddingException | CertificateException | IOException e) {
-                    Slog.e(TAG, "Failed to decrypt child profile key", e);
-                }
-            }
-        }
-        try {
-            // Clear all the users credentials could have been installed in for this user.
-            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
-                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
-                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
-                }
-            }
-        } finally {
-            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
-                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
-                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
-            }
-        }
-    }
-
-    @Override
-    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
-            int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, true, challenge, userId,
-                null /* progressCallback */);
-    }
-
-    /**
-     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
-     * format.
-     */
-    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
-            boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (TextUtils.isEmpty(credential)) {
-            throw new IllegalArgumentException("Credential can't be null or empty");
-        }
-        synchronized (mSpManager) {
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
-                        credentialType, hasChallenge, challenge, userId, progressCallback);
-                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-                }
-                return response;
-            }
-        }
-        CredentialHash storedHash = mStorage.readCredentialHash(userId);
-        if (storedHash.type != credentialType) {
-            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
-                    + " stored: " + storedHash.type + " passed in: " + credentialType);
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
-                && storedHash.isBaseZeroPattern;
-
-        String credentialToVerify;
-        if (shouldReEnrollBaseZero) {
-            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
-        } else {
-            credentialToVerify = credential;
-        }
-
-        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
-                hasChallenge, challenge, progressCallback);
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
-            if (shouldReEnrollBaseZero) {
-                setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId);
-            }
-        }
-
-        return response;
-    }
-
-    @Override
-    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
-            long challenge, int userId) throws RemoteException {
-        checkPasswordReadPermission(userId);
-        if (!isManagedProfileWithUnifiedLock(userId)) {
-            throw new RemoteException("User id must be managed profile with unified lock");
-        }
-        final int parentProfileId = mUserManager.getProfileParent(userId).id;
-        // Unlock parent by using parent's challenge
-        final VerifyCredentialResponse parentResponse = doVerifyCredential(
-                credential,
-                type,
-                true /* hasChallenge */,
-                challenge,
-                parentProfileId,
-                null /* progressCallback */);
-        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-            // Failed, just return parent's response
-            return parentResponse;
-        }
-
-        try {
-            // Unlock work profile, and work profile with unified lock must use password only
-            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    true,
-                    challenge,
-                    userId, null /* progressCallback */);
-        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                | NoSuchAlgorithmException | NoSuchPaddingException
-                | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                | BadPaddingException | CertificateException | IOException e) {
-            Slog.e(TAG, "Failed to decrypt child profile key", e);
-            throw new RemoteException("Unable to get tied profile token");
-        }
-    }
-
-    /**
-     * Lowest-level credential verification routine that talks to GateKeeper. If verification
-     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
-     * hash to GK.
-     */
-    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
-            String credential, boolean hasChallenge, long challenge,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
-            // don't need to pass empty credentials to GateKeeper
-            return VerifyCredentialResponse.OK;
-        }
-
-        if (storedHash == null || TextUtils.isEmpty(credential)) {
-            return VerifyCredentialResponse.ERROR;
-        }
-
-        // We're potentially going to be doing a bunch of disk I/O below as part
-        // of unlocking the user, so yell if calling from the main thread.
-        StrictMode.noteDiskRead();
-
-        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
-            final byte[] hash;
-            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
-            } else {
-                hash = mLockPatternUtils.passwordToHash(credential, userId);
-            }
-            if (Arrays.equals(hash, storedHash.hash)) {
-                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
-                } else {
-                    unlockKeystore(credential, userId);
-                }
-                // Users with legacy credentials don't have credential-backed
-                // FBE keys, so just pass through a fake token/secret
-                Slog.i(TAG, "Unlocking user with fake token: " + userId);
-                final byte[] fakeToken = String.valueOf(userId).getBytes();
-                unlockUser(userId, fakeToken, fakeToken);
-
-                // migrate credential to GateKeeper
-                setLockCredentialInternal(credential, storedHash.type, null, userId);
-                if (!hasChallenge) {
-                    notifyActivePasswordMetricsAvailable(credential, userId);
-                    return VerifyCredentialResponse.OK;
-                }
-                // Fall through to get the auth token. Technically this should never happen,
-                // as a user that had a legacy credential would have to unlock their device
-                // before getting to a flow with a challenge, but supporting for consistency.
-            } else {
-                return VerifyCredentialResponse.ERROR;
-            }
-        }
-        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
-                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
-        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
-        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
-
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-
-            // credential has matched
-
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(credential, userId);
-            unlockKeystore(credential, userId);
-
-            Slog.i(TAG, "Unlocking user " + userId + " with token length "
-                    + response.getPayload().length);
-            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            if (shouldReEnroll) {
-                setLockCredentialInternal(credential, storedHash.type, credential, userId);
-            } else {
-                // Now that we've cleared of all required GK migration, let's do the final
-                // migration to synthetic password.
-                synchronized (mSpManager) {
-                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
-                                storedHash.hash, credential, storedHash.type, userId);
-                        activateEscrowTokens(auth, userId);
-                    }
-                }
-            }
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
-        final PasswordMetrics metrics;
-        if (password == null) {
-            metrics = new PasswordMetrics();
-        } else {
-            metrics = PasswordMetrics.computeForPassword(password);
-            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
-        }
-
-        // Asynchronous to avoid dead lock
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.setActivePasswordState(metrics, userId);
-        });
-    }
-
-    /**
-     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
-     * reporting the password changed.
-     */
-    private void notifyPasswordChanged(@UserIdInt int userId) {
-        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
-        mHandler.post(() -> {
-            DevicePolicyManager dpm = (DevicePolicyManager)
-                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-            dpm.reportPasswordChanged(userId);
-        });
-    }
-
-    @Override
-    public boolean checkVoldPassword(int userId) throws RemoteException {
-        if (!mFirstCallToVold) {
-            return false;
-        }
-        mFirstCallToVold = false;
-
-        checkPasswordReadPermission(userId);
-
-        // There's no guarantee that this will safely connect, but if it fails
-        // we will simply show the lock screen when we shouldn't, so relatively
-        // benign. There is an outside chance something nasty would happen if
-        // this service restarted before vold stales out the password in this
-        // case. The nastiness is limited to not showing the lock screen when
-        // we should, within the first minute of decrypting the phone if this
-        // service can't connect to vold, it restarts, and then the new instance
-        // does successfully connect.
-        final IStorageManager service = mInjector.getStorageManager();
-        String password;
-        long identity = Binder.clearCallingIdentity();
-        try {
-            password = service.getPassword();
-            service.clearPassword();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (password == null) {
-            return false;
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        try {
-            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
-                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
-                        null /* progressCallback */)
-                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    return true;
-                }
-            }
-        } catch (Exception e) {
-        }
-
-        return false;
-    }
-
-    private void removeUser(int userId, boolean unknownUser) {
-        mSpManager.removeUser(userId);
-        mStorage.removeUser(userId);
-        mStrongAuth.removeUser(userId);
-
-        final KeyStore ks = KeyStore.getInstance();
-        ks.onUserRemoved(userId);
-
-        try {
-            final IGateKeeperService gk = getGateKeeperService();
-            if (gk != null) {
-                gk.clearSecureUserId(userId);
-            }
-        } catch (RemoteException ex) {
-            Slog.w(TAG, "unable to clear GK secure user id");
-        }
-        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
-            removeKeystoreProfileKey(userId);
-        }
-    }
-
-    private void removeKeystoreProfileKey(int targetUserId) {
-        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
-        try {
-            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
-            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            // We have tried our best to remove all keys
-            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
-        }
-    }
-
-    @Override
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.registerStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        checkPasswordReadPermission(UserHandle.USER_ALL);
-        mStrongAuth.unregisterStrongAuthTracker(tracker);
-    }
-
-    @Override
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
-    }
-
-    @Override
-    public void userPresent(int userId) {
-        checkWritePermission(userId);
-        mStrongAuth.reportUnlock(userId);
-    }
-
-    @Override
-    public int getStrongAuthForUser(int userId) {
-        checkPasswordReadPermission(userId);
-        return mStrongAuthTracker.getStrongAuthForUser(userId);
-    }
-
-    private boolean isCallerShell() {
-        final int callingUid = Binder.getCallingUid();
-        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
-    }
-
-    private void enforceShell() {
-        if (!isCallerShell()) {
-            throw new SecurityException("Caller must be shell");
-        }
-    }
-
-    @Override
-    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
-            throws RemoteException {
-        enforceShell();
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
-                    this, in, out, err, args, callback, resultReceiver);
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    private static final String[] VALID_SETTINGS = new String[] {
-            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
-            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
-            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
-            LockPatternUtils.LOCKSCREEN_OPTIONS,
-            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
-            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
-            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            Secure.LOCK_PATTERN_ENABLED,
-            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
-            Secure.LOCK_PATTERN_VISIBLE,
-            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
-    };
-
-    // Reading these settings needs the contacts permission
-    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    // Reading these settings needs the same permission as checking the password
-    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            SEPARATE_PROFILE_CHALLENGE_KEY
-    };
-
-    private static final String[] SETTINGS_TO_BACKUP = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
-            mGateKeeperService = null;
-        }
-    }
-
-    protected synchronized IGateKeeperService getGateKeeperService()
-            throws RemoteException {
-        if (mGateKeeperService != null) {
-            return mGateKeeperService;
-        }
-
-        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
-        if (service != null) {
-            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
-            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
-            return mGateKeeperService;
-        }
-
-        Slog.e(TAG, "Unable to acquire GateKeeperService");
-        return null;
-    }
-
-    /**
-     * Precondition: vold and keystore unlocked.
-     *
-     * Create new synthetic password, set up synthetic password blob protected by the supplied
-     * user credential, and make the newly-created SP blob active.
-     *
-     * The invariant under a synthetic password is:
-     * 1. If user credential exists, then both vold and keystore and protected with keys derived
-     *     from the synthetic password.
-     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
-     *     make it consistent with current behaviour. It also allows ActivityManager to call
-     *     unlockUser() with empty secret.
-     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
-     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
-     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
-     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
-     *     credential change, in which case we have no way to derive the existing synthetic password
-     *     and has to create a new one.
-     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
-     *     clears/re-creates his lockscreen PIN.
-     *
-     *
-     * Different cases of calling this method:
-     * 1. credentialHash != null
-     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
-     *     migrated to associate with the new SP.
-     *     This happens during a normal migration case when the user currently has password.
-     *
-     * 2. credentialhash == null and credential == null
-     *     A new SP blob and a new SID will be created, while the user has no credentials.
-     *     This can happens when we are activating an escrow token on a unsecured device, during
-     *     which we want to create the SP structure with an empty user credential.
-     *
-     * 3. credentialhash == null and credential != null
-     *     This is the untrusted credential reset, OR the user sets a new lockscreen password
-     *     FOR THE FIRST TIME on a SP-enabled device. New credential and new SID will be created
-     */
-    private AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
-            String credential, int credentialType, int userId) throws RemoteException {
-        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
-        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
-                credentialHash, credential, userId);
-        if (auth == null) {
-            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
-            return null;
-        }
-        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        if (credential != null) {
-            if (credentialHash == null) {
-                // Since when initializing SP, we didn't provide an existing password handle
-                // for it to migrate SID, we need to create a new SID for the user.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-            }
-            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-        } else {
-            clearUserKeyProtection(userId);
-            setKeystorePassword(null, userId);
-            getGateKeeperService().clearSecureUserId(userId);
-        }
-        fixateNewestUserKeyAuth(userId);
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
-        return auth;
-    }
-
-    private long getSyntheticPasswordHandleLocked(int userId) {
-        try {
-            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
-        } catch (RemoteException e) {
-            return SyntheticPasswordManager.DEFAULT_HANDLE;
-        }
-    }
-
-    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        // This is a global setting
-        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
-    }
-
-    private void enableSyntheticPasswordLocked() throws RemoteException {
-        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
-            credentialType, boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
-        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            userCredential = null;
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, userCredential, userId);
-
-        VerifyCredentialResponse response = authResult.gkResponse;
-        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-            // credential has matched
-            // perform verifyChallenge with synthetic password which generates the real auth
-            // token for the current user
-            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
-                    challenge, userId);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                Slog.wtf(TAG, "verifyChallenge with SP failed.");
-                return VerifyCredentialResponse.ERROR;
-            }
-            if (progressCallback != null) {
-                progressCallback.onCredentialVerified();
-            }
-            notifyActivePasswordMetricsAvailable(userCredential, userId);
-            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
-
-            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
-            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
-            unlockUser(userId, null, secret);
-
-            if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
-            }
-            activateEscrowTokens(authResult.authToken, userId);
-        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
-            if (response.getTimeout() > 0) {
-                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
-            }
-        }
-
-        return response;
-    }
-
-    /**
-     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
-     * on an existing authentication token. Even though a new SP blob is created, the underlying
-     * synthetic password is never changed.
-     *
-     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
-     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
-     * added back when new password is set in future.
-     */
-    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
-            AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
-        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
-                credential, credentialType, auth, userId);
-        final Map<Integer, String> profilePasswords;
-        if (credential != null) {
-            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = null;
-
-            if (mSpManager.hasSidForUser(userId)) {
-                // We are changing password of a secured device, nothing more needed as
-                // createPasswordBasedSyntheticPassword has already taken care of maintaining
-                // the password handle and SID unchanged.
-
-                //refresh auth token
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-            } else {
-                // A new password is set on a previously-unsecured device, we need to generate
-                // a new SID, and re-add keys to vold and keystore.
-                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
-                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
-                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
-                fixateNewestUserKeyAuth(userId);
-                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
-            }
-        } else {
-            // Cache all profile password if they use unified work challenge. This will later be
-            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
-            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
-
-            // we are clearing password of a secured device, so need to nuke SID as well.
-            mSpManager.clearSidForUser(userId);
-            getGateKeeperService().clearSecureUserId(userId);
-            // Clear key from vold so ActivityManager can just unlock the user with empty secret
-            // during boot.
-            clearUserKeyProtection(userId);
-            fixateNewestUserKeyAuth(userId);
-            setKeystorePassword(null, userId);
-        }
-        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
-        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
-        return newHandle;
-    }
-
-    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
-            String savedCredential, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
-        if (isManagedProfileWithUnifiedLock(userId)) {
-            // get credential from keystore when managed profile has unified lock
-            try {
-                savedCredential = getDecryptedPasswordForTiedProfile(userId);
-            } catch (FileNotFoundException e) {
-                Slog.i(TAG, "Child profile key not found");
-            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
-                    | NoSuchAlgorithmException | NoSuchPaddingException
-                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
-                    | BadPaddingException | CertificateException | IOException e) {
-                Slog.e(TAG, "Failed to decrypt child profile key", e);
-            }
-        }
-        long handle = getSyntheticPasswordHandleLocked(userId);
-        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
-                getGateKeeperService(), handle, savedCredential, userId);
-        VerifyCredentialResponse response = authResult.gkResponse;
-        AuthenticationToken auth = authResult.authToken;
-        if (auth != null) {
-            // We are performing a trusted credential change i.e. a correct existing credential
-            // is provided
-            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else if (response != null
-                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
-            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
-            // So provision a new SP and SID. This would invalidate existing escrow tokens.
-            // Still support this for now but this flow will be removed in the next release.
-
-            Slog.w(TAG, "Untrusted credential change invoked");
-            initializeSyntheticPasswordLocked(null, credential, credentialType, userId);
-            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
-        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
-            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
-                    (response != null ? "rate limit exceeded" : "failed"));
-            return;
-        }
-        notifyActivePasswordMetricsAvailable(credential, userId);
-
-    }
-
-    @Override
-    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
-        synchronized (mSpManager) {
-            enableSyntheticPasswordLocked();
-            // Migrate to synthetic password based credentials if the user has no password,
-            // the token can then be activated immediately.
-            AuthenticationToken auth = null;
-            if (!isUserSecure(userId)) {
-                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
-                    auth = initializeSyntheticPasswordLocked(null, null,
-                            LockPatternUtils.CREDENTIAL_TYPE_NONE, userId);
-                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
-                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
-                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
-                            pwdHandle, null, userId).authToken;
-                }
-            }
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-                if (!mSpManager.hasEscrowData(userId)) {
-                    throw new SecurityException("Escrow token is disabled on the current user");
-                }
-            }
-            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
-            if (auth != null) {
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-            return handle;
-        }
-    }
-
-    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
-        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
-        synchronized (mSpManager) {
-            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
-                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
-                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
-            }
-        }
-    }
-
-    @Override
-    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            return mSpManager.existsHandle(handle, userId);
-        }
-    }
-
-    @Override
-    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        synchronized (mSpManager) {
-            if (handle == getSyntheticPasswordHandleLocked(userId)) {
-                Slog.w(TAG, "Cannot remove password handle");
-                return false;
-            }
-            if (mSpManager.removePendingToken(handle, userId)) {
-                return true;
-            }
-            if (mSpManager.existsHandle(handle, userId)) {
-                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
-            byte[] token, int userId) throws RemoteException {
-        ensureCallerSystemUid();
-        boolean result;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
-                    userId);
-        }
-        if (result) {
-            synchronized (mSeparateChallengeLock) {
-                setSeparateProfileChallengeEnabled(userId, true, null);
-            }
-            notifyPasswordChanged(userId);
-        }
-        return result;
-    }
-
-    private boolean setLockCredentialWithTokenInternal(String credential, int type,
-            long tokenHandle, byte[] token, int userId) throws RemoteException {
-        synchronized (mSpManager) {
-            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
-                    getGateKeeperService(), tokenHandle, token, userId);
-            if (result.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return false;
-            }
-            long oldHandle = getSyntheticPasswordHandleLocked(userId);
-            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, userId);
-            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
-            return true;
-        }
-    }
-
-    @Override
-    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
-            throws RemoteException {
-        ensureCallerSystemUid();
-        AuthenticationResult authResult;
-        synchronized (mSpManager) {
-            if (!mSpManager.hasEscrowData(userId)) {
-                throw new SecurityException("Escrow token is disabled on the current user");
-            }
-            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
-                    tokenHandle, token, userId);
-            if (authResult.authToken == null) {
-                Slog.w(TAG, "Invalid escrow token supplied");
-                return;
-            }
-        }
-        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-
-        synchronized (this) {
-            pw.println("Current lock settings service state:");
-            pw.println(String.format("SP Enabled = %b",
-                    mLockPatternUtils.isSyntheticPasswordEnabled()));
-
-            List<UserInfo> users = mUserManager.getUsers();
-            for (int user = 0; user < users.size(); user++) {
-                final int userId = users.get(user).id;
-                pw.println("    User " + userId);
-                pw.println(String.format("        SP Handle = %x",
-                        getSyntheticPasswordHandleLocked(userId)));
-                try {
-                    pw.println(String.format("        SID = %x",
-                            getGateKeeperService().getSecureUserId(userId)));
-                } catch (RemoteException e) {
-                    // ignore.
-                }
-            }
-        }
-    }
-
-    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
-        long ident = Binder.clearCallingIdentity();
-        try {
-            // Managed profile should have escrow enabled
-            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
-                Slog.i(TAG, "Managed profile can have escrow token");
-                return;
-            }
-            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
-            // Devices with Device Owner should have escrow enabled on all users.
-            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
-                Slog.i(TAG, "Corp-owned device can have escrow token");
-                return;
-            }
-            // We could also have a profile owner on the given (non-managed) user for unicorn cases
-            if (dpm.getProfileOwnerAsUser(userId) != null) {
-                Slog.i(TAG, "User with profile owner can have escrow token");
-                return;
-            }
-            // If the device is yet to be provisioned (still in SUW), there is still
-            // a chance that Device Owner will be set on the device later, so postpone
-            // disabling escrow token for now.
-            if (!dpm.isDeviceProvisioned()) {
-                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
-                return;
-            }
-
-            // Escrow tokens are enabled on automotive builds.
-            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                return;
-            }
-
-            // Disable escrow token permanently on all other device/user types.
-            Slog.i(TAG, "Disabling escrow token on user " + userId);
-            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
-                mSpManager.destroyEscrowData(userId);
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    private void ensureCallerSystemUid() throws SecurityException {
-        final int callingUid = mInjector.binderGetCallingUid();
-        if (callingUid != Process.SYSTEM_UID) {
-            throw new SecurityException("Only system can call this API.");
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java
deleted file mode 100644
index 9d671e39..0000000
--- a/services/core/java/com/android/server/LockSettingsShellCommand.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ShellCommand;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
-
-class LockSettingsShellCommand extends ShellCommand {
-
-    private static final String COMMAND_SET_PATTERN = "set-pattern";
-    private static final String COMMAND_SET_PIN = "set-pin";
-    private static final String COMMAND_SET_PASSWORD = "set-password";
-    private static final String COMMAND_CLEAR = "clear";
-    private static final String COMMAND_SP = "sp";
-    private static final String COMMAND_SET_DISABLED = "set-disabled";
-
-    private int mCurrentUserId;
-    private final LockPatternUtils mLockPatternUtils;
-    private final Context mContext;
-    private String mOld = "";
-    private String mNew = "";
-
-    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
-        mContext = context;
-        mLockPatternUtils = lockPatternUtils;
-    }
-
-    @Override
-    public int onCommand(String cmd) {
-        try {
-            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
-
-            parseArgs();
-            if (!checkCredential()) {
-                return -1;
-            }
-            switch (cmd) {
-                case COMMAND_SET_PATTERN:
-                    runSetPattern();
-                    break;
-                case COMMAND_SET_PASSWORD:
-                    runSetPassword();
-                    break;
-                case COMMAND_SET_PIN:
-                    runSetPin();
-                    break;
-                case COMMAND_CLEAR:
-                    runClear();
-                    break;
-                case COMMAND_SP:
-                    runEnableSp();
-                    break;
-                case COMMAND_SET_DISABLED:
-                    runSetDisabled();
-                    break;
-                default:
-                    getErrPrintWriter().println("Unknown command: " + cmd);
-                    break;
-            }
-            return 0;
-        } catch (Exception e) {
-            getErrPrintWriter().println("Error while executing command: " + cmd);
-            e.printStackTrace(getErrPrintWriter());
-            return -1;
-        }
-    }
-
-    @Override
-    public void onHelp() {
-    }
-
-    private void parseArgs() {
-        String opt;
-        while ((opt = getNextOption()) != null) {
-            if ("--old".equals(opt)) {
-                mOld = getNextArgRequired();
-            } else if ("--user".equals(opt)) {
-                mCurrentUserId = Integer.parseInt(getNextArgRequired());
-            } else {
-                getErrPrintWriter().println("Unknown option: " + opt);
-                throw new IllegalArgumentException();
-            }
-        }
-        mNew = getNextArg();
-    }
-
-    private void runEnableSp() {
-        if (mNew != null) {
-            mLockPatternUtils.enableSyntheticPassword();
-            getOutPrintWriter().println("Synthetic password enabled");
-        }
-        getOutPrintWriter().println(String.format("SP Enabled = %b",
-                mLockPatternUtils.isSyntheticPasswordEnabled()));
-    }
-
-    private void runSetPattern() throws RemoteException {
-        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
-        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
-    }
-
-    private void runSetPassword() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
-        getOutPrintWriter().println("Password set to '" + mNew + "'");
-    }
-
-    private void runSetPin() throws RemoteException {
-        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
-        getOutPrintWriter().println("Pin set to '" + mNew + "'");
-    }
-
-    private void runClear() throws RemoteException {
-        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
-        getOutPrintWriter().println("Lock credential cleared");
-    }
-
-    private void runSetDisabled() throws RemoteException {
-        final boolean disabled = Boolean.parseBoolean(mNew);
-        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
-        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
-    }
-
-    private boolean checkCredential() throws RemoteException, RequestThrottledException {
-        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
-        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
-        if (havePassword || havePattern) {
-            boolean result;
-            if (havePassword) {
-                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
-            } else {
-                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
-                        mCurrentUserId);
-            }
-            if (result) {
-                return true;
-            } else {
-                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
deleted file mode 100644
index 761ae44..0000000
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static android.content.Context.USER_SERVICE;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.os.Environment;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Storage for the lock settings service.
- */
-class LockSettingsStorage {
-
-    private static final String TAG = "LockSettingsStorage";
-    private static final String TABLE = "locksettings";
-    private static final boolean DEBUG = false;
-
-    private static final String COLUMN_KEY = "name";
-    private static final String COLUMN_USERID = "user";
-    private static final String COLUMN_VALUE = "value";
-
-    private static final String[] COLUMNS_FOR_QUERY = {
-            COLUMN_VALUE
-    };
-    private static final String[] COLUMNS_FOR_PREFETCH = {
-            COLUMN_KEY, COLUMN_VALUE
-    };
-
-    private static final String SYSTEM_DIRECTORY = "/system/";
-    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
-    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
-    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
-    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
-    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
-    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
-
-    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
-
-    private static final Object DEFAULT = new Object();
-
-    private final DatabaseHelper mOpenHelper;
-    private final Context mContext;
-    private final Cache mCache = new Cache();
-    private final Object mFileWriteLock = new Object();
-
-    @VisibleForTesting
-    public static class CredentialHash {
-        static final int VERSION_LEGACY = 0;
-        static final int VERSION_GATEKEEPER = 1;
-
-        private CredentialHash(byte[] hash, int type, int version) {
-            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                if (hash == null) {
-                    throw new RuntimeException("Empty hash for CredentialHash");
-                }
-            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
-                if (hash != null) {
-                    throw new RuntimeException("None type CredentialHash should not have hash");
-                }
-            }
-            this.hash = hash;
-            this.type = type;
-            this.version = version;
-            this.isBaseZeroPattern = false;
-        }
-
-        private CredentialHash(byte[] hash, boolean isBaseZeroPattern) {
-            this.hash = hash;
-            this.type = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-            this.version = VERSION_GATEKEEPER;
-            this.isBaseZeroPattern = isBaseZeroPattern;
-        }
-
-        static CredentialHash create(byte[] hash, int type) {
-            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-                throw new RuntimeException("Bad type for CredentialHash");
-            }
-            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
-        }
-
-        static CredentialHash createEmptyHash() {
-            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                    VERSION_GATEKEEPER);
-        }
-
-        byte[] hash;
-        int type;
-        int version;
-        boolean isBaseZeroPattern;
-    }
-
-    public LockSettingsStorage(Context context) {
-        mContext = context;
-        mOpenHelper = new DatabaseHelper(context);
-    }
-
-    public void setDatabaseOnCreateCallback(Callback callback) {
-        mOpenHelper.setCallback(callback);
-    }
-
-    public void writeKeyValue(String key, String value, int userId) {
-        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
-    }
-
-    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
-        ContentValues cv = new ContentValues();
-        cv.put(COLUMN_KEY, key);
-        cv.put(COLUMN_USERID, userId);
-        cv.put(COLUMN_VALUE, value);
-
-        db.beginTransaction();
-        try {
-            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
-                    new String[] {key, Integer.toString(userId)});
-            db.insert(TABLE, null, cv);
-            db.setTransactionSuccessful();
-            mCache.putKeyValue(key, value, userId);
-        } finally {
-            db.endTransaction();
-        }
-
-    }
-
-    public String readKeyValue(String key, String defaultValue, int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasKeyValue(key, userId)) {
-                return mCache.peekKeyValue(key, defaultValue, userId);
-            }
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        Object result = DEFAULT;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
-                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
-                new String[] { Integer.toString(userId), key },
-                null, null, null)) != null) {
-            if (cursor.moveToFirst()) {
-                result = cursor.getString(0);
-            }
-            cursor.close();
-        }
-        mCache.putKeyValueIfUnchanged(key, result, userId, version);
-        return result == DEFAULT ? defaultValue : (String) result;
-    }
-
-    public void prefetchUser(int userId) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.isFetched(userId)) {
-                return;
-            }
-            mCache.setFetched(userId);
-            version = mCache.getVersion();
-        }
-
-        Cursor cursor;
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
-                COLUMN_USERID + "=?",
-                new String[] { Integer.toString(userId) },
-                null, null, null)) != null) {
-            while (cursor.moveToNext()) {
-                String key = cursor.getString(0);
-                String value = cursor.getString(1);
-                mCache.putKeyValueIfUnchanged(key, value, userId, version);
-            }
-            cursor.close();
-        }
-
-        // Populate cache by reading the password and pattern files.
-        readCredentialHash(userId);
-    }
-
-    private CredentialHash readPasswordHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getLegacyLockPasswordFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    private CredentialHash readPatternHashIfExists(int userId) {
-        byte[] stored = readFile(getLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_GATEKEEPER);
-        }
-
-        stored = readFile(getBaseZeroLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, true);
-        }
-
-        stored = readFile(getLegacyLockPatternFilename(userId));
-        if (!ArrayUtils.isEmpty(stored)) {
-            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                    CredentialHash.VERSION_LEGACY);
-        }
-        return null;
-    }
-
-    public CredentialHash readCredentialHash(int userId) {
-        CredentialHash passwordHash = readPasswordHashIfExists(userId);
-        CredentialHash patternHash = readPatternHashIfExists(userId);
-        if (passwordHash != null && patternHash != null) {
-            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
-                return passwordHash;
-            } else {
-                return patternHash;
-            }
-        } else if (passwordHash != null) {
-            return passwordHash;
-        } else if (patternHash != null) {
-            return patternHash;
-        } else {
-            return CredentialHash.createEmptyHash();
-        }
-    }
-
-    public void removeChildProfileLock(int userId) {
-        if (DEBUG)
-            Slog.e(TAG, "Remove child profile lock for user: " + userId);
-        try {
-            deleteFile(getChildProfileLockFile(userId));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void writeChildProfileLock(int userId, byte[] lock) {
-        writeFile(getChildProfileLockFile(userId), lock);
-    }
-
-    public byte[] readChildProfileLock(int userId) {
-        return readFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasChildProfileLock(int userId) {
-        return hasFile(getChildProfileLockFile(userId));
-    }
-
-    public boolean hasPassword(int userId) {
-        return hasFile(getLockPasswordFilename(userId)) ||
-            hasFile(getLegacyLockPasswordFilename(userId));
-    }
-
-    public boolean hasPattern(int userId) {
-        return hasFile(getLockPatternFilename(userId)) ||
-            hasFile(getBaseZeroLockPatternFilename(userId)) ||
-            hasFile(getLegacyLockPatternFilename(userId));
-    }
-
-    public boolean hasCredential(int userId) {
-        return hasPassword(userId) || hasPattern(userId);
-    }
-
-    private boolean hasFile(String name) {
-        byte[] contents = readFile(name);
-        return contents != null && contents.length > 0;
-    }
-
-    private byte[] readFile(String name) {
-        int version;
-        synchronized (mCache) {
-            if (mCache.hasFile(name)) {
-                return mCache.peekFile(name);
-            }
-            version = mCache.getVersion();
-        }
-
-        RandomAccessFile raf = null;
-        byte[] stored = null;
-        try {
-            raf = new RandomAccessFile(name, "r");
-            stored = new byte[(int) raf.length()];
-            raf.readFully(stored, 0, stored.length);
-            raf.close();
-        } catch (IOException e) {
-            Slog.e(TAG, "Cannot read file " + e);
-        } finally {
-            if (raf != null) {
-                try {
-                    raf.close();
-                } catch (IOException e) {
-                    Slog.e(TAG, "Error closing file " + e);
-                }
-            }
-        }
-        mCache.putFileIfUnchanged(name, stored, version);
-        return stored;
-    }
-
-    private void writeFile(String name, byte[] hash) {
-        synchronized (mFileWriteLock) {
-            RandomAccessFile raf = null;
-            try {
-                // Write the hash to file
-                raf = new RandomAccessFile(name, "rw");
-                // Truncate the file if pattern is null, to clear the lock
-                if (hash == null || hash.length == 0) {
-                    raf.setLength(0);
-                } else {
-                    raf.write(hash, 0, hash.length);
-                }
-                raf.close();
-            } catch (IOException e) {
-                Slog.e(TAG, "Error writing to file " + e);
-            } finally {
-                if (raf != null) {
-                    try {
-                        raf.close();
-                    } catch (IOException e) {
-                        Slog.e(TAG, "Error closing file " + e);
-                    }
-                }
-            }
-            mCache.putFile(name, hash);
-        }
-    }
-
-    private void deleteFile(String name) {
-        if (DEBUG) Slog.e(TAG, "Delete file " + name);
-        synchronized (mFileWriteLock) {
-            File file = new File(name);
-            if (file.exists()) {
-                file.delete();
-                mCache.putFile(name, null);
-            }
-        }
-    }
-
-    public void writeCredentialHash(CredentialHash hash, int userId) {
-        byte[] patternHash = null;
-        byte[] passwordHash = null;
-
-        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            passwordHash = hash.hash;
-        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
-            patternHash = hash.hash;
-        }
-        writeFile(getLockPasswordFilename(userId), passwordHash);
-        writeFile(getLockPatternFilename(userId), patternHash);
-    }
-
-    @VisibleForTesting
-    String getLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getLegacyLockPasswordFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
-    }
-
-    private String getBaseZeroLockPatternFilename(int userId) {
-        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
-    }
-
-    @VisibleForTesting
-    String getChildProfileLockFile(int userId) {
-        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
-    }
-
-    private String getLockCredentialFilePathForUser(int userId, String basename) {
-        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
-                        SYSTEM_DIRECTORY;
-        if (userId == 0) {
-            // Leave it in the same place for user 0
-            return dataSystemDirectory + basename;
-        } else {
-            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
-        }
-    }
-
-    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
-        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
-    }
-
-    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
-        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
-    }
-
-    public void deleteSyntheticPasswordState(int userId, long handle, String name, boolean secure) {
-        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
-        File file = new File(path);
-        if (file.exists()) {
-            //TODO: (b/34600579) invoke secdiscardable
-            file.delete();
-            mCache.putFile(path, null);
-        }
-    }
-
-    public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
-        Map<Integer, List<Long>> result = new ArrayMap<>();
-        final UserManager um = UserManager.get(mContext);
-        for (UserInfo user : um.getUsers(false)) {
-            result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
-        }
-        return result;
-    }
-
-    public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
-        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
-        List<Long> result = new ArrayList<>();
-        File[] files = baseDir.listFiles();
-        if (files == null) {
-            return result;
-        }
-        for (File file : files) {
-            String[] parts = file.getName().split("\\.");
-            if (parts.length == 2 && parts[1].equals(stateName)) {
-                try {
-                    result.add(Long.parseUnsignedLong(parts[0], 16));
-                } catch (NumberFormatException e) {
-                    Slog.e(TAG, "Failed to parse handle " + parts[0]);
-                }
-            }
-        }
-        return result;
-    }
-
-    @VisibleForTesting
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
-    }
-
-    @VisibleForTesting
-    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
-            String name) {
-        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
-        String baseName = String.format("%016x.%s", handle, name);
-        if (!baseDir.exists()) {
-            baseDir.mkdir();
-        }
-        return new File(baseDir, baseName).getAbsolutePath();
-    }
-
-    public void removeUser(int userId) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
-        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
-        final UserInfo parentInfo = um.getProfileParent(userId);
-
-        if (parentInfo == null) {
-            // This user owns its lock settings files - safe to delete them
-            synchronized (mFileWriteLock) {
-                String name = getLockPasswordFilename(userId);
-                File file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-                name = getLockPatternFilename(userId);
-                file = new File(name);
-                if (file.exists()) {
-                    file.delete();
-                    mCache.putFile(name, null);
-                }
-            }
-        } else {
-            // Managed profile
-            removeChildProfileLock(userId);
-        }
-
-        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
-        try {
-            db.beginTransaction();
-            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
-            db.setTransactionSuccessful();
-            mCache.removeUser(userId);
-            // The directory itself will be deleted as part of user deletion operation by the
-            // framework, so only need to purge cache here.
-            //TODO: (b/34600579) invoke secdiscardable
-            mCache.purgePath(spStateDir.getAbsolutePath());
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    @VisibleForTesting
-    void closeDatabase() {
-        mOpenHelper.close();
-    }
-
-    @VisibleForTesting
-    void clearCache() {
-        mCache.clear();
-    }
-
-    public interface Callback {
-        void initialize(SQLiteDatabase db);
-    }
-
-    class DatabaseHelper extends SQLiteOpenHelper {
-        private static final String TAG = "LockSettingsDB";
-        private static final String DATABASE_NAME = "locksettings.db";
-
-        private static final int DATABASE_VERSION = 2;
-
-        private Callback mCallback;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            setWriteAheadLoggingEnabled(true);
-        }
-
-        public void setCallback(Callback callback) {
-            mCallback = callback;
-        }
-
-        private void createTable(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    COLUMN_KEY + " TEXT," +
-                    COLUMN_USERID + " INTEGER," +
-                    COLUMN_VALUE + " TEXT" +
-                    ");");
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            createTable(db);
-            if (mCallback != null) {
-                mCallback.initialize(db);
-            }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            int upgradeVersion = oldVersion;
-            if (upgradeVersion == 1) {
-                // Previously migrated lock screen widget settings. Now defunct.
-                upgradeVersion = 2;
-            }
-
-            if (upgradeVersion != DATABASE_VERSION) {
-                Log.w(TAG, "Failed to upgrade database!");
-            }
-        }
-    }
-
-    /**
-     * Cache consistency model:
-     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
-     *   section either provided by the database transaction or mWriteLock, such that writes to the
-     *   cache and writes to the backing storage are guaranteed to occur in the same order
-     *
-     * - Reads can populate the cache, but because they are no strong ordering guarantees with
-     *   respect to writes this precaution is taken:
-     *   - The cache is assigned a version number that increases every time the cache is modified.
-     *     Reads from backing storage can only populate the cache if the backing storage
-     *     has not changed since the load operation has begun.
-     *     This guarantees that no read operation can shadow a write to the cache that happens
-     *     after it had begun.
-     */
-    private static class Cache {
-        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
-        private final CacheKey mCacheKey = new CacheKey();
-        private int mVersion = 0;
-
-        String peekKeyValue(String key, String defaultValue, int userId) {
-            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
-            return cached == DEFAULT ? defaultValue : (String) cached;
-        }
-
-        boolean hasKeyValue(String key, int userId) {
-            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
-        }
-
-        void putKeyValue(String key, String value, int userId) {
-            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
-        }
-
-        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
-            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
-        }
-
-        byte[] peekFile(String fileName) {
-            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        boolean hasFile(String fileName) {
-            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
-        }
-
-        void putFile(String key, byte[] value) {
-            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
-        }
-
-        void putFileIfUnchanged(String key, byte[] value, int version) {
-            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
-        }
-
-        void setFetched(int userId) {
-            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
-        }
-
-        boolean isFetched(int userId) {
-            return contains(CacheKey.TYPE_FETCHED, "", userId);
-        }
-
-
-        private synchronized void put(int type, String key, Object value, int userId) {
-            // Create a new CachKey here because it may be saved in the map if the key is absent.
-            mCache.put(new CacheKey().set(type, key, userId), value);
-            mVersion++;
-        }
-
-        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
-                int version) {
-            if (!contains(type, key, userId) && mVersion == version) {
-                put(type, key, value, userId);
-            }
-        }
-
-        private synchronized boolean contains(int type, String key, int userId) {
-            return mCache.containsKey(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized Object peek(int type, String key, int userId) {
-            return mCache.get(mCacheKey.set(type, key, userId));
-        }
-
-        private synchronized int getVersion() {
-            return mVersion;
-        }
-
-        synchronized void removeUser(int userId) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                if (mCache.keyAt(i).userId == userId) {
-                    mCache.removeAt(i);
-                }
-            }
-
-            // Make sure in-flight loads can't write to cache.
-            mVersion++;
-        }
-
-        synchronized void purgePath(String path) {
-            for (int i = mCache.size() - 1; i >= 0; i--) {
-                CacheKey entry = mCache.keyAt(i);
-                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
-                    mCache.removeAt(i);
-                }
-            }
-            mVersion++;
-        }
-
-        synchronized void clear() {
-            mCache.clear();
-            mVersion++;
-        }
-
-        private static final class CacheKey {
-            static final int TYPE_KEY_VALUE = 0;
-            static final int TYPE_FILE = 1;
-            static final int TYPE_FETCHED = 2;
-
-            String key;
-            int userId;
-            int type;
-
-            public CacheKey set(int type, String key, int userId) {
-                this.type = type;
-                this.key = key;
-                this.userId = userId;
-                return this;
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                if (!(obj instanceof CacheKey))
-                    return false;
-                CacheKey o = (CacheKey) obj;
-                return userId == o.userId && type == o.type && key.equals(o.key);
-            }
-
-            @Override
-            public int hashCode() {
-                return key.hashCode() ^ userId ^ type;
-            }
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
deleted file mode 100644
index f5fe3db..0000000
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
-import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
-
-import android.app.AlarmManager;
-import android.app.AlarmManager.OnAlarmListener;
-import android.app.admin.DevicePolicyManager;
-import android.app.trust.IStrongAuthTracker;
-import android.content.Context;
-import android.os.Binder;
-import android.os.DeadObjectException;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-import android.util.SparseIntArray;
-
-import java.util.ArrayList;
-
-/**
- * Keeps track of requests for strong authentication.
- */
-public class LockSettingsStrongAuth {
-
-    private static final String TAG = "LockSettings";
-
-    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
-    private static final int MSG_REGISTER_TRACKER = 2;
-    private static final int MSG_UNREGISTER_TRACKER = 3;
-    private static final int MSG_REMOVE_USER = 4;
-    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
-
-    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
-            "LockSettingsStrongAuth.timeoutForUser";
-
-    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
-    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
-    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
-            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
-    private final int mDefaultStrongAuthFlags;
-    private final Context mContext;
-
-    private AlarmManager mAlarmManager;
-
-    public LockSettingsStrongAuth(Context context) {
-        mContext = context;
-        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
-        mAlarmManager = context.getSystemService(AlarmManager.class);
-    }
-
-    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                return;
-            }
-        }
-        mStrongAuthTrackers.add(tracker);
-
-        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-            int key = mStrongAuthForUser.keyAt(i);
-            int value = mStrongAuthForUser.valueAt(i);
-            try {
-                tracker.onStrongAuthRequiredChanged(value, key);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
-                mStrongAuthTrackers.remove(i);
-                return;
-            }
-        }
-    }
-
-    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
-                int key = mStrongAuthForUser.keyAt(i);
-                handleRequireStrongAuthOneUser(strongAuthReason, key);
-            }
-        } else {
-            handleRequireStrongAuthOneUser(strongAuthReason, userId);
-        }
-    }
-
-    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
-        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
-        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
-                ? STRONG_AUTH_NOT_REQUIRED
-                : (oldValue | strongAuthReason);
-        if (oldValue != newValue) {
-            mStrongAuthForUser.put(userId, newValue);
-            notifyStrongAuthTrackers(newValue, userId);
-        }
-    }
-
-    private void handleRemoveUser(int userId) {
-        int index = mStrongAuthForUser.indexOfKey(userId);
-        if (index >= 0) {
-            mStrongAuthForUser.removeAt(index);
-            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
-        }
-    }
-
-    private void handleScheduleStrongAuthTimeout(int userId) {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
-        // cancel current alarm listener for the user (if there was one)
-        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
-        if (alarm != null) {
-            mAlarmManager.cancel(alarm);
-        } else {
-            alarm = new StrongAuthTimeoutAlarmListener(userId);
-            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
-        }
-        // schedule a new alarm listener for the user
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
-                alarm, mHandler);
-    }
-
-    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
-        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
-            try {
-                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
-            } catch (DeadObjectException e) {
-                Slog.d(TAG, "Removing dead StrongAuthTracker.");
-                mStrongAuthTrackers.remove(i);
-                i--;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
-            }
-        }
-    }
-
-    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
-        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
-    }
-
-    public void removeUser(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
-    }
-
-    public void requireStrongAuth(int strongAuthReason, int userId) {
-        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
-            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
-                    userId).sendToTarget();
-        } else {
-            throw new IllegalArgumentException(
-                    "userId must be an explicit user id or USER_ALL");
-        }
-    }
-
-    public void reportUnlock(int userId) {
-        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
-    }
-
-    public void reportSuccessfulStrongAuthUnlock(int userId) {
-        final int argNotUsed = 0;
-        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
-    }
-
-    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
-
-        private final int mUserId;
-
-        public StrongAuthTimeoutAlarmListener(int userId) {
-            mUserId = userId;
-        }
-
-        @Override
-        public void onAlarm() {
-            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_REGISTER_TRACKER:
-                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_UNREGISTER_TRACKER:
-                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
-                    break;
-                case MSG_REQUIRE_STRONG_AUTH:
-                    handleRequireStrongAuth(msg.arg1, msg.arg2);
-                    break;
-                case MSG_REMOVE_USER:
-                    handleRemoveUser(msg.arg1);
-                    break;
-                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
-                    handleScheduleStrongAuthTimeout(msg.arg1);
-                    break;
-            }
-        }
-    };
-}
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index d74bc19..d762214 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -100,11 +100,7 @@
             ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
                 @Override
                 public void onChange(boolean selfChange) {
-                    if (isNsdEnabled()) {
-                        mNsdStateMachine.sendMessage(NsdManager.ENABLE);
-                    } else {
-                        mNsdStateMachine.sendMessage(NsdManager.DISABLE);
-                    }
+                    notifyEnabled(isNsdEnabled());
                 }
             };
 
@@ -118,11 +114,8 @@
             addState(mDefaultState);
                 addState(mDisabledState, mDefaultState);
                 addState(mEnabledState, mDefaultState);
-            if (isNsdEnabled()) {
-                setInitialState(mEnabledState);
-            } else {
-                setInitialState(mDisabledState);
-            }
+            State initialState = isNsdEnabled() ? mEnabledState : mDisabledState;
+            setInitialState(initialState);
             setLogRecSize(25);
             registerForNsdSetting();
         }
@@ -571,25 +564,22 @@
         return new Messenger(mNsdStateMachine.getHandler());
     }
 
-    public void setEnabled(boolean enable) {
+    public void setEnabled(boolean isEnabled) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
                 "NsdService");
-        mNsdSettings.putEnabledStatus(enable);
-        if (enable) {
-            mNsdStateMachine.sendMessage(NsdManager.ENABLE);
-        } else {
-            mNsdStateMachine.sendMessage(NsdManager.DISABLE);
-        }
+        mNsdSettings.putEnabledStatus(isEnabled);
+        notifyEnabled(isEnabled);
     }
 
-    private void sendNsdStateChangeBroadcast(boolean enabled) {
+    private void notifyEnabled(boolean isEnabled) {
+        mNsdStateMachine.sendMessage(isEnabled ? NsdManager.ENABLE : NsdManager.DISABLE);
+    }
+
+    private void sendNsdStateChangeBroadcast(boolean isEnabled) {
         final Intent intent = new Intent(NsdManager.ACTION_NSD_STATE_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        if (enabled) {
-            intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_ENABLED);
-        } else {
-            intent.putExtra(NsdManager.EXTRA_NSD_STATE, NsdManager.NSD_STATE_DISABLED);
-        }
+        int nsdState = isEnabled ? NsdManager.NSD_STATE_ENABLED : NsdManager.NSD_STATE_DISABLED;
+        intent.putExtra(NsdManager.EXTRA_NSD_STATE, nsdState);
         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
     }
 
diff --git a/services/core/java/com/android/server/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/SyntheticPasswordCrypto.java
deleted file mode 100644
index 71ab2a5..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordCrypto.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.util.Arrays;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-public class SyntheticPasswordCrypto {
-    private static final int PROFILE_KEY_IV_SIZE = 12;
-    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
-    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
-    // Time between the user credential is verified with GK and the decryption of synthetic password
-    // under the auth-bound key. This should always happen one after the other, but give it 15
-    // seconds just to be sure.
-    private static final int USER_AUTHENTICATION_VALIDITY = 15;
-
-    private static byte[] decrypt(SecretKey key, byte[] blob)
-            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
-            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
-        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
-        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
-                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
-        return cipher.doFinal(ciphertext);
-    }
-
-    private static byte[] encrypt(SecretKey key, byte[] blob)
-            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
-            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
-        if (blob == null) {
-            return null;
-        }
-        Cipher cipher = Cipher.getInstance(
-                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
-                        + KeyProperties.ENCRYPTION_PADDING_NONE);
-        cipher.init(Cipher.ENCRYPT_MODE, key);
-        byte[] ciphertext = cipher.doFinal(blob);
-        byte[] iv = cipher.getIV();
-        if (iv.length != PROFILE_KEY_IV_SIZE) {
-            throw new RuntimeException("Invalid iv length: " + iv.length);
-        }
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        outputStream.write(iv);
-        outputStream.write(ciphertext);
-        return outputStream.toByteArray();
-    }
-
-    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return encrypt(key, message);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException | IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
-        byte[] keyHash = personalisedHash(personalisation, keyBytes);
-        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
-                KeyProperties.KEY_ALGORITHM_AES);
-        try {
-            return decrypt(key, ciphertext);
-        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
-                | IllegalBlockSizeException | BadPaddingException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
-        try {
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-
-            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
-            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
-            return decrypt(decryptionKey, intermediate);
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException | UnrecoverableKeyException
-                | InvalidAlgorithmParameterException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to decrypt blob", e);
-        }
-    }
-
-    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
-        try {
-            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
-            keyGenerator.init(new SecureRandom());
-            SecretKey secretKey = keyGenerator.generateKey();
-            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
-                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
-                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
-                    .setCriticalToDeviceEncryption(true);
-            if (sid != 0) {
-                builder.setUserAuthenticationRequired(true)
-                        .setBoundToSpecificSecureUserId(sid)
-                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
-            }
-
-            keyStore.setEntry(keyAlias,
-                    new KeyStore.SecretKeyEntry(secretKey),
-                    builder.build());
-            byte[] intermediate = encrypt(secretKey, data);
-            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
-
-        } catch (CertificateException | IOException | BadPaddingException
-                | IllegalBlockSizeException
-                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
-                | InvalidKeyException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to encrypt blob", e);
-        }
-    }
-
-    public static void destroyBlobKey(String keyAlias) {
-        KeyStore keyStore;
-        try {
-            keyStore = KeyStore.getInstance("AndroidKeyStore");
-            keyStore.load(null);
-            keyStore.deleteEntry(keyAlias);
-        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
-                | IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
-        try {
-            final int PADDING_LENGTH = 128;
-            MessageDigest digest = MessageDigest.getInstance("SHA-512");
-            if (personalisation.length > PADDING_LENGTH) {
-                throw new RuntimeException("Personalisation too long");
-            }
-            // Personalize the hash
-            // Pad it to the block size of the hash function
-            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
-            digest.update(personalisation);
-            for (byte[] data : message) {
-                digest.update(data);
-            }
-            return digest.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/SyntheticPasswordManager.java b/services/core/java/com/android/server/SyntheticPasswordManager.java
deleted file mode 100644
index 6722bc5..0000000
--- a/services/core/java/com/android/server/SyntheticPasswordManager.java
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.weaver.V1_0.IWeaver;
-import android.hardware.weaver.V1_0.WeaverConfig;
-import android.hardware.weaver.V1_0.WeaverReadResponse;
-import android.hardware.weaver.V1_0.WeaverReadStatus;
-import android.hardware.weaver.V1_0.WeaverStatus;
-import android.os.RemoteException;
-import android.security.GateKeeper;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-
-import libcore.util.HexEncoding;
-
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-
-/**
- * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
- * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
- * synthetic password blobs which are wrapped by user credentials or escrow tokens.
- *
- * Here is the assumptions it makes:
- *   Each user has one single synthetic password at any time.
- *   The SP has an associated password handle, which binds to the SID for that user. The password
- *   handle is persisted by SyntheticPasswordManager internally.
- *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
- *
- * Information persisted on disk:
- *   for each user (stored under DEFAULT_HANDLE):
- *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
- *                     credential exists, cleared when user clears their credential.
- *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
- *                     tokens. Destroyed when escrow support is turned off for the given user.
- *
- *     for each SP blob under the user (stored under the corresponding handle):
- *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
- *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
- *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
- *                            purpose of secure deletion. Exists if this is a non-weaver SP
- *                            (both password and token based), or it's a token-based SP under weaver.
- *       WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
- *
- *
- */
-public class SyntheticPasswordManager {
-    private static final String SP_BLOB_NAME = "spblob";
-    private static final String SP_E0_NAME = "e0";
-    private static final String SP_P1_NAME = "p1";
-    private static final String SP_HANDLE_NAME = "handle";
-    private static final String SECDISCARDABLE_NAME = "secdis";
-    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
-    private static final String PASSWORD_DATA_NAME = "pwd";
-    private static final String WEAVER_SLOT_NAME = "weaver";
-
-    public static final long DEFAULT_HANDLE = 0L;
-    private static final String DEFAULT_PASSWORD = "default-password";
-
-    private static final byte WEAVER_VERSION = 1;
-    private static final int INVALID_WEAVER_SLOT = -1;
-
-    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
-    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
-    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
-
-    // 256-bit synthetic password
-    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
-
-    private static final int PASSWORD_SCRYPT_N = 11;
-    private static final int PASSWORD_SCRYPT_R = 3;
-    private static final int PASSWORD_SCRYPT_P = 1;
-    private static final int PASSWORD_SALT_LENGTH = 16;
-    private static final int PASSWORD_TOKEN_LENGTH = 32;
-    private static final String TAG = "SyntheticPasswordManager";
-
-    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
-    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
-    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
-    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
-    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
-    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
-    private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
-    private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes();
-    private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes();
-
-    static class AuthenticationResult {
-        public AuthenticationToken authToken;
-        public VerifyCredentialResponse gkResponse;
-    }
-
-    static class AuthenticationToken {
-        /*
-         * Here is the relationship between all three fields:
-         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
-         * syntheticPassword = hash(P0 || P1)
-         * E0 = P0 encrypted under syntheticPassword, stored on disk.
-         */
-        private @Nullable byte[] E0;
-        private @Nullable byte[] P1;
-        private @NonNull String syntheticPassword;
-
-        public String deriveKeyStorePassword() {
-            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
-                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
-        }
-
-        public byte[] deriveGkPassword() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
-                    syntheticPassword.getBytes());
-        }
-
-        public byte[] deriveDiskEncryptionKey() {
-            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
-                    syntheticPassword.getBytes());
-        }
-
-        private void initialize(byte[] P0, byte[] P1) {
-            this.P1 = P1;
-            this.syntheticPassword = String.valueOf(HexEncoding.encode(
-                    SyntheticPasswordCrypto.personalisedHash(
-                            PERSONALIZATION_SP_SPLIT, P0, P1)));
-            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
-                    PERSONALIZATION_E0, P0);
-        }
-
-        public void recreate(byte[] secret) {
-            initialize(secret, this.P1);
-        }
-
-        protected static AuthenticationToken create() {
-            AuthenticationToken result = new AuthenticationToken();
-            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
-                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
-            return result;
-        }
-
-        public byte[] computeP0() {
-            if (E0 == null) {
-                return null;
-            }
-            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
-                    E0);
-        }
-    }
-
-    static class PasswordData {
-        byte scryptN;
-        byte scryptR;
-        byte scryptP;
-        public int passwordType;
-        byte[] salt;
-        // For GateKeeper-based credential, this is the password handle returned by GK,
-        // for weaver-based credential, this is empty.
-        public byte[] passwordHandle;
-
-        public static PasswordData create(int passwordType) {
-            PasswordData result = new PasswordData();
-            result.scryptN = PASSWORD_SCRYPT_N;
-            result.scryptR = PASSWORD_SCRYPT_R;
-            result.scryptP = PASSWORD_SCRYPT_P;
-            result.passwordType = passwordType;
-            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
-            return result;
-        }
-
-        public static PasswordData fromBytes(byte[] data) {
-            PasswordData result = new PasswordData();
-            ByteBuffer buffer = ByteBuffer.allocate(data.length);
-            buffer.put(data, 0, data.length);
-            buffer.flip();
-            result.passwordType = buffer.getInt();
-            result.scryptN = buffer.get();
-            result.scryptR = buffer.get();
-            result.scryptP = buffer.get();
-            int saltLen = buffer.getInt();
-            result.salt = new byte[saltLen];
-            buffer.get(result.salt);
-            int handleLen = buffer.getInt();
-            if (handleLen > 0) {
-                result.passwordHandle = new byte[handleLen];
-                buffer.get(result.passwordHandle);
-            } else {
-                result.passwordHandle = null;
-            }
-            return result;
-        }
-
-        public byte[] toBytes() {
-
-            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
-                    + Integer.BYTES + salt.length + Integer.BYTES +
-                    (passwordHandle != null ? passwordHandle.length : 0));
-            buffer.putInt(passwordType);
-            buffer.put(scryptN);
-            buffer.put(scryptR);
-            buffer.put(scryptP);
-            buffer.putInt(salt.length);
-            buffer.put(salt);
-            if (passwordHandle != null && passwordHandle.length > 0) {
-                buffer.putInt(passwordHandle.length);
-                buffer.put(passwordHandle);
-            } else {
-                buffer.putInt(0);
-            }
-            return buffer.array();
-        }
-    }
-
-    static class TokenData {
-        byte[] secdiscardableOnDisk;
-        byte[] weaverSecret;
-        byte[] aggregatedSecret;
-    }
-
-    private LockSettingsStorage mStorage;
-    private IWeaver mWeaver;
-    private WeaverConfig mWeaverConfig;
-
-    public SyntheticPasswordManager(LockSettingsStorage storage) {
-        mStorage = storage;
-    }
-
-    @VisibleForTesting
-    protected IWeaver getWeaverService() throws RemoteException {
-        try {
-            return IWeaver.getService();
-        } catch (NoSuchElementException e) {
-            Slog.i(TAG, "Device does not support weaver");
-            return null;
-        }
-    }
-
-    public synchronized void initWeaverService() {
-        if (mWeaver != null) {
-            return;
-        }
-        try {
-            mWeaverConfig = null;
-            mWeaver = getWeaverService();
-            if (mWeaver != null) {
-                mWeaver.getConfig((int status, WeaverConfig config) -> {
-                    if (status == WeaverStatus.OK && config.slots > 0) {
-                        mWeaverConfig = config;
-                    } else {
-                        Slog.e(TAG, "Failed to get weaver config, status " + status
-                                + " slots: " + config.slots);
-                        mWeaver = null;
-                    }
-                });
-            }
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to get weaver service", e);
-        }
-    }
-
-    private synchronized boolean isWeaverAvailable() {
-        if (mWeaver == null) {
-            //Re-initializing weaver in case there was a transient error preventing access to it.
-            initWeaverService();
-        }
-        return mWeaver != null && mWeaverConfig.slots > 0;
-    }
-
-    /**
-     * Enroll the given key value pair into the specified weaver slot. if the given key is null,
-     * a default all-zero key is used. If the value is not specified, a fresh random secret is
-     * generated as the value.
-     *
-     * @return the value stored in the weaver slot
-     * @throws RemoteException
-     */
-    private byte[] weaverEnroll(int slot, byte[] key, @Nullable byte[] value)
-            throws RemoteException {
-        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
-            throw new RuntimeException("Invalid slot for weaver");
-        }
-        if (key == null) {
-            key = new byte[mWeaverConfig.keySize];
-        } else if (key.length != mWeaverConfig.keySize) {
-            throw new RuntimeException("Invalid key size for weaver");
-        }
-        if (value == null) {
-            value = secureRandom(mWeaverConfig.valueSize);
-        }
-        int writeStatus = mWeaver.write(slot, toByteArrayList(key), toByteArrayList(value));
-        if (writeStatus != WeaverStatus.OK) {
-            Log.e(TAG, "weaver write failed, slot: " + slot + " status: " + writeStatus);
-            return null;
-        }
-        return value;
-    }
-
-    /**
-     * Verify the supplied key against a weaver slot, returning a response indicating whether
-     * the verification is successful, throttled or failed. If successful, the bound secret
-     * is also returned.
-     * @throws RemoteException
-     */
-    private VerifyCredentialResponse weaverVerify(int slot, byte[] key) throws RemoteException {
-        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
-            throw new RuntimeException("Invalid slot for weaver");
-        }
-        if (key == null) {
-            key = new byte[mWeaverConfig.keySize];
-        } else if (key.length != mWeaverConfig.keySize) {
-            throw new RuntimeException("Invalid key size for weaver");
-        }
-        final VerifyCredentialResponse[] response = new VerifyCredentialResponse[1];
-        mWeaver.read(slot, toByteArrayList(key), (int status, WeaverReadResponse readResponse) -> {
-            switch (status) {
-                case WeaverReadStatus.OK:
-                    response[0] = new VerifyCredentialResponse(
-                            fromByteArrayList(readResponse.value));
-                    break;
-                case WeaverReadStatus.THROTTLE:
-                    response[0] = new VerifyCredentialResponse(readResponse.timeout);
-                    Log.e(TAG, "weaver read failed (THROTTLE), slot: " + slot);
-                    break;
-                case WeaverReadStatus.INCORRECT_KEY:
-                    if (readResponse.timeout == 0) {
-                        response[0] = VerifyCredentialResponse.ERROR;
-                        Log.e(TAG, "weaver read failed (INCORRECT_KEY), slot: " + slot);
-                    } else {
-                        response[0] = new VerifyCredentialResponse(readResponse.timeout);
-                        Log.e(TAG, "weaver read failed (INCORRECT_KEY/THROTTLE), slot: " + slot);
-                    }
-                    break;
-                case WeaverReadStatus.FAILED:
-                    response[0] = VerifyCredentialResponse.ERROR;
-                    Log.e(TAG, "weaver read failed (FAILED), slot: " + slot);
-                    break;
-               default:
-                   response[0] = VerifyCredentialResponse.ERROR;
-                   Log.e(TAG, "weaver read unknown status " + status + ", slot: " + slot);
-                   break;
-            }
-        });
-        return response[0];
-    }
-
-    public void removeUser(int userId) {
-        if (isWeaverAvailable()) {
-            for (long handle : mStorage.listSyntheticPasswordHandlesForUser(WEAVER_SLOT_NAME,
-                    userId)) {
-                destroyWeaverSlot(handle, userId);
-            }
-        }
-    }
-
-    public int getCredentialType(long handle, int userId) {
-        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
-        if (passwordData == null) {
-            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
-            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
-        }
-        return PasswordData.fromBytes(passwordData).passwordType;
-    }
-
-    /**
-     * Initializing a new Authentication token, possibly from an existing credential and hash.
-     *
-     * The authentication token would bear a randomly-generated synthetic password.
-     *
-     * This method has the side effect of rebinding the SID of the given user to the
-     * newly-generated SP.
-     *
-     * If the existing credential hash is non-null, the existing SID mill be migrated so
-     * the synthetic password in the authentication token will produce the same SID
-     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
-     * in a per-user data storage.)
-     *
-     * If the existing credential hash is null, it means the given user should have no SID so
-     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
-     * the supplied credential parameter is also ignored.
-     *
-     * Also saves the escrow information necessary to re-generate the synthetic password under
-     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
-     * password escrow should be disabled completely on the given user.
-     *
-     */
-    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
-            byte[] hash, String credential, int userId) throws RemoteException {
-        AuthenticationToken result = AuthenticationToken.create();
-        GateKeeperResponse response;
-        if (hash != null) {
-            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
-                    result.deriveGkPassword());
-            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
-                clearSidForUser(userId);
-            } else {
-                saveSyntheticPasswordHandle(response.getPayload(), userId);
-            }
-        } else {
-            clearSidForUser(userId);
-        }
-        saveEscrowData(result, userId);
-        return result;
-    }
-
-    /**
-     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
-     * Used when adding password to previously-unsecured devices.
-     */
-    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
-            int userId) throws RemoteException {
-        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
-                authToken.deriveGkPassword());
-        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-            Log.e(TAG, "Fail to create new SID for user " + userId);
-            return;
-        }
-        saveSyntheticPasswordHandle(response.getPayload(), userId);
-    }
-
-    // Nuke the SP handle (and as a result, its SID) for the given user.
-    public void clearSidForUser(int userId) {
-        destroyState(SP_HANDLE_NAME, true, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasSidForUser(int userId) {
-        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    // if null, it means there is no SID associated with the user
-    // This can happen if the user is migrated to SP but currently
-    // do not have a lockscreen password.
-    private byte[] loadSyntheticPasswordHandle(int userId) {
-        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
-        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
-    }
-
-    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
-        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
-        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-        return authToken.E0 != null && authToken.P1 != null;
-    }
-
-    private void saveEscrowData(AuthenticationToken authToken, int userId) {
-        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
-        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
-    }
-
-    public boolean hasEscrowData(int userId) {
-        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
-                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
-    }
-
-    public void destroyEscrowData(int userId) {
-        destroyState(SP_E0_NAME, true, DEFAULT_HANDLE, userId);
-        destroyState(SP_P1_NAME, true, DEFAULT_HANDLE, userId);
-    }
-
-    private int loadWeaverSlot(long handle, int userId) {
-        final int LENGTH = Byte.BYTES + Integer.BYTES;
-        byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
-        if (data == null || data.length != LENGTH) {
-            return INVALID_WEAVER_SLOT;
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(LENGTH);
-        buffer.put(data, 0, data.length);
-        buffer.flip();
-        if (buffer.get() != WEAVER_VERSION) {
-            Log.e(TAG, "Invalid weaver slot version of handle " + handle);
-            return INVALID_WEAVER_SLOT;
-        }
-        return buffer.getInt();
-    }
-
-    private void saveWeaverSlot(int slot, long handle, int userId) {
-        ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
-        buffer.put(WEAVER_VERSION);
-        buffer.putInt(slot);
-        saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
-    }
-
-    private void destroyWeaverSlot(long handle, int userId) {
-        int slot = loadWeaverSlot(handle, userId);
-        if (slot != INVALID_WEAVER_SLOT) {
-            try {
-                weaverEnroll(slot, null, null);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to destroy slot", e);
-            }
-        }
-        destroyState(WEAVER_SLOT_NAME, true, handle, userId);
-    }
-
-    private int getNextAvailableWeaverSlot() {
-        Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
-                WEAVER_SLOT_NAME);
-        HashSet<Integer> slots = new HashSet<>();
-        for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
-            for (Long handle : entry.getValue()) {
-                int slot = loadWeaverSlot(handle, entry.getKey());
-                slots.add(slot);
-            }
-        }
-        for (int i = 0; i < mWeaverConfig.slots; i++) {
-            if (!slots.contains(i)) {
-                return i;
-            }
-        }
-        throw new RuntimeException("Run out of weaver slots.");
-    }
-
-    /**
-     * Create a new password based SP blob based on the supplied authentication token, such that
-     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
-     * in the same authentication token.
-     *
-     * This method only creates SP blob wrapping around the given synthetic password and does not
-     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
-     * is consistent with the device state by calling other APIs in this class.
-     *
-     * @see #newSidForUser
-     * @see #clearSidForUser
-     */
-    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            String credential, int credentialType, AuthenticationToken authToken, int userId)
-                    throws RemoteException {
-        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
-            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
-            credential = DEFAULT_PASSWORD;
-        }
-
-        long handle = generateHandle();
-        PasswordData pwd = PasswordData.create(credentialType);
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-        final long sid;
-        final byte[] applicationId;
-
-        if (isWeaverAvailable()) {
-            // Weaver based user password
-            int weaverSlot = getNextAvailableWeaverSlot();
-            byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
-            if (weaverSecret == null) {
-                Log.e(TAG, "Fail to enroll user password under weaver " + userId);
-                return DEFAULT_HANDLE;
-            }
-            saveWeaverSlot(weaverSlot, handle, userId);
-
-            pwd.passwordHandle = null;
-            sid = GateKeeper.INVALID_SECURE_USER_ID;
-            applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
-        } else {
-            // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
-            // to prevent them from accumulating and causing problems.
-            gatekeeper.clearSecureUserId(fakeUid(userId));
-            // GateKeeper based user password
-            GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
-                    passwordTokenToGkInput(pwdToken));
-            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
-                Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
-                return DEFAULT_HANDLE;
-            }
-            pwd.passwordHandle = response.getPayload();
-            sid = sidFromPasswordHandle(pwd.passwordHandle);
-            applicationId = transformUnderSecdiscardable(pwdToken,
-                    createSecdiscardable(handle, userId));
-        }
-        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
-                applicationId, sid, userId);
-        return handle;
-    }
-
-    private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
-
-    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
-        long handle = generateHandle();
-        if (!tokenMap.containsKey(userId)) {
-            tokenMap.put(userId, new ArrayMap<>());
-        }
-        TokenData tokenData = new TokenData();
-        final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH);
-        if (isWeaverAvailable()) {
-            tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize);
-            tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret,
-                            PERSONALISATION_WEAVER_TOKEN, secdiscardable);
-        } else {
-            tokenData.secdiscardableOnDisk = secdiscardable;
-            tokenData.weaverSecret = null;
-        }
-        tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
-
-        tokenMap.get(userId).put(handle, tokenData);
-        return handle;
-    }
-
-    public Set<Long> getPendingTokensForUser(int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return Collections.emptySet();
-        }
-        return tokenMap.get(userId).keySet();
-    }
-
-    public boolean removePendingToken(long handle, int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        return tokenMap.get(userId).remove(handle) != null;
-    }
-
-    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
-            int userId) {
-        if (!tokenMap.containsKey(userId)) {
-            return false;
-        }
-        TokenData tokenData = tokenMap.get(userId).get(handle);
-        if (tokenData == null) {
-            return false;
-        }
-        if (!loadEscrowData(authToken, userId)) {
-            Log.w(TAG, "User is not escrowable");
-            return false;
-        }
-        if (isWeaverAvailable()) {
-            int slot = getNextAvailableWeaverSlot();
-            try {
-                weaverEnroll(slot, null, tokenData.weaverSecret);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to enroll weaver secret when activating token", e);
-                return false;
-            }
-            saveWeaverSlot(slot, handle, userId);
-        }
-        saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
-        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
-                tokenData.aggregatedSecret, 0L, userId);
-        tokenMap.get(userId).remove(handle);
-        return true;
-    }
-
-    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
-            byte[] applicationId, long sid, int userId) {
-        final byte[] secret;
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            secret = authToken.computeP0();
-        } else {
-            secret = authToken.syntheticPassword.getBytes();
-        }
-        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
-        byte[] blob = new byte[content.length + 1 + 1];
-        blob[0] = SYNTHETIC_PASSWORD_VERSION;
-        blob[1] = type;
-        System.arraycopy(content, 0, blob, 2, content.length);
-        saveState(SP_BLOB_NAME, blob, handle, userId);
-    }
-
-    /**
-     * Decrypt a synthetic password by supplying the user credential and corresponding password
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
-     */
-    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
-            long handle, String credential, int userId) throws RemoteException {
-        if (credential == null) {
-            credential = DEFAULT_PASSWORD;
-        }
-        AuthenticationResult result = new AuthenticationResult();
-        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
-        byte[] pwdToken = computePasswordToken(credential, pwd);
-
-        final byte[] applicationId;
-        int weaverSlot = loadWeaverSlot(handle, userId);
-        if (weaverSlot != INVALID_WEAVER_SLOT) {
-            // Weaver based user password
-            if (!isWeaverAvailable()) {
-                Log.e(TAG, "No weaver service to unwrap password based SP");
-                result.gkResponse = VerifyCredentialResponse.ERROR;
-                return result;
-            }
-            result.gkResponse = weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken));
-            if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
-                return result;
-            }
-            applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload());
-        } else {
-            byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
-            GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
-                    pwd.passwordHandle, gkPwdToken);
-            int responseCode = response.getResponseCode();
-            if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-                result.gkResponse = VerifyCredentialResponse.OK;
-                if (response.getShouldReEnroll()) {
-                    GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
-                            pwd.passwordHandle, gkPwdToken, gkPwdToken);
-                    if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                        pwd.passwordHandle = reenrollResponse.getPayload();
-                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
-                    } else {
-                        Log.w(TAG, "Fail to re-enroll user password for user " + userId);
-                        // continue the flow anyway
-                    }
-                }
-            } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-                result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
-                return result;
-            } else  {
-                result.gkResponse = VerifyCredentialResponse.ERROR;
-                return result;
-            }
-            applicationId = transformUnderSecdiscardable(pwdToken,
-                    loadSecdiscardable(handle, userId));
-        }
-
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
-                applicationId, userId);
-
-        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
-        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-        return result;
-    }
-
-    /**
-     * Decrypt a synthetic password by supplying an escrow token and corresponding token
-     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
-     * verification to referesh the SID & Auth token maintained by the system.
-     */
-    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
-            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
-                    throws RemoteException {
-        AuthenticationResult result = new AuthenticationResult();
-        byte[] secdiscardable = loadSecdiscardable(handle, userId);
-        int slotId = loadWeaverSlot(handle, userId);
-        if (slotId != INVALID_WEAVER_SLOT) {
-            if (!isWeaverAvailable()) {
-                Log.e(TAG, "No weaver service to unwrap token based SP");
-                result.gkResponse = VerifyCredentialResponse.ERROR;
-                return result;
-            }
-            VerifyCredentialResponse response = weaverVerify(slotId, null);
-            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
-                    response.getPayload() == null) {
-                Log.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
-                result.gkResponse = VerifyCredentialResponse.ERROR;
-                return result;
-            }
-            secdiscardable = SyntheticPasswordCrypto.decrypt(response.getPayload(),
-                    PERSONALISATION_WEAVER_TOKEN, secdiscardable);
-        }
-        byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
-        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
-                applicationId, userId);
-        if (result.authToken != null) {
-            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
-            if (result.gkResponse == null) {
-                // The user currently has no password. return OK with null payload so null
-                // is propagated to unlockUser()
-                result.gkResponse = VerifyCredentialResponse.OK;
-            }
-        } else {
-            result.gkResponse = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
-            byte[] applicationId, int userId) {
-        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
-        if (blob == null) {
-            return null;
-        }
-        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
-            throw new RuntimeException("Unknown blob version");
-        }
-        if (blob[1] != type) {
-            throw new RuntimeException("Invalid blob type");
-        }
-        byte[] secret = decryptSPBlob(getHandleName(handle),
-                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
-        if (secret == null) {
-            Log.e(TAG, "Fail to decrypt SP for user " + userId);
-            return null;
-        }
-        AuthenticationToken result = new AuthenticationToken();
-        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
-            if (!loadEscrowData(result, userId)) {
-                Log.e(TAG, "User is not escrowable: " + userId);
-                return null;
-            }
-            result.recreate(secret);
-        } else {
-            result.syntheticPassword = new String(secret);
-        }
-        return result;
-    }
-
-    /**
-     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
-     * if required.
-     *
-     * Normally performing verifyChallenge with an AuthenticationToken should always return
-     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
-     * decrypt SP.
-     */
-    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
-            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
-        byte[] spHandle = loadSyntheticPasswordHandle(userId);
-        if (spHandle == null) {
-            // There is no password handle associated with the given user, i.e. the user is not
-            // secured by lockscreen and has no SID, so just return here;
-            return null;
-        }
-        VerifyCredentialResponse result;
-        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
-                spHandle, auth.deriveGkPassword());
-        int responseCode = response.getResponseCode();
-        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
-            result = new VerifyCredentialResponse(response.getPayload());
-            if (response.getShouldReEnroll()) {
-                response = gatekeeper.enroll(userId, spHandle,
-                        spHandle, auth.deriveGkPassword());
-                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
-                    spHandle = response.getPayload();
-                    saveSyntheticPasswordHandle(spHandle, userId);
-                    // Call self again to re-verify with updated handle
-                    return verifyChallenge(gatekeeper, auth, challenge, userId);
-                } else {
-                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
-                    // Fall through, return existing handle
-                }
-            }
-        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
-            result = new VerifyCredentialResponse(response.getTimeout());
-        } else {
-            result = VerifyCredentialResponse.ERROR;
-        }
-        return result;
-    }
-
-    public boolean existsHandle(long handle, int userId) {
-        return hasState(SP_BLOB_NAME, handle, userId);
-    }
-
-    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
-    }
-
-    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
-        destroySyntheticPassword(handle, userId);
-        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
-        destroyState(PASSWORD_DATA_NAME, true, handle, userId);
-    }
-
-    private void destroySyntheticPassword(long handle, int userId) {
-        destroyState(SP_BLOB_NAME, true, handle, userId);
-        destroySPBlobKey(getHandleName(handle));
-        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
-            destroyWeaverSlot(handle, userId);
-        }
-    }
-
-    private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) {
-        byte[] weaverSecret = SyntheticPasswordCrypto.personalisedHash(
-                PERSONALISATION_WEAVER_PASSWORD, secret);
-        byte[] result = new byte[data.length + weaverSecret.length];
-        System.arraycopy(data, 0, result, 0, data.length);
-        System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length);
-        return result;
-    }
-
-    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
-        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
-                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
-        byte[] result = new byte[data.length + secdiscardable.length];
-        System.arraycopy(data, 0, result, 0, data.length);
-        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
-        return result;
-    }
-
-    private byte[] createSecdiscardable(long handle, int userId) {
-        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
-        saveSecdiscardable(handle, data, userId);
-        return data;
-    }
-
-    private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
-        saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
-    }
-
-    private byte[] loadSecdiscardable(long handle, int userId) {
-        return loadState(SECDISCARDABLE_NAME, handle, userId);
-    }
-
-    private boolean hasState(String stateName, long handle, int userId) {
-        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
-    }
-
-    private byte[] loadState(String stateName, long handle, int userId) {
-        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
-    }
-
-    private void saveState(String stateName, byte[] data, long handle, int userId) {
-        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
-    }
-
-    private void destroyState(String stateName, boolean secure, long handle, int userId) {
-        mStorage.deleteSyntheticPasswordState(userId, handle, stateName, secure);
-    }
-
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
-    }
-
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
-    }
-
-    protected void destroySPBlobKey(String keyAlias) {
-        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
-    }
-
-    public static long generateHandle() {
-        SecureRandom rng = new SecureRandom();
-        long result;
-        do {
-            result = rng.nextLong();
-        } while (result == DEFAULT_HANDLE);
-        return result;
-    }
-
-    private int fakeUid(int uid) {
-        return 100000 + uid;
-    }
-
-    protected static byte[] secureRandom(int length) {
-        try {
-            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private String getHandleName(long handle) {
-        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
-    }
-
-    private byte[] computePasswordToken(String password, PasswordData data) {
-        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
-                PASSWORD_TOKEN_LENGTH);
-    }
-
-    private byte[] passwordTokenToGkInput(byte[] token) {
-        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
-    }
-
-    private byte[] passwordTokenToWeaverKey(byte[] token) {
-        byte[] key = SyntheticPasswordCrypto.personalisedHash(PERSONALISATION_WEAVER_KEY, token);
-        if (key.length < mWeaverConfig.keySize) {
-            throw new RuntimeException("weaver key length too small");
-        }
-        return Arrays.copyOf(key, mWeaverConfig.keySize);
-    }
-
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return nativeSidFromPasswordHandle(handle);
-    }
-
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
-    }
-
-    native long nativeSidFromPasswordHandle(byte[] handle);
-    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
-
-    protected static ArrayList<Byte> toByteArrayList(byte[] data) {
-        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
-        for (int i = 0; i < data.length; i++) {
-            result.add(data[i]);
-        }
-        return result;
-    }
-
-    protected static byte[] fromByteArrayList(ArrayList<Byte> data) {
-        byte[] result = new byte[data.size()];
-        for (int i = 0; i < data.size(); i++) {
-            result[i] = data.get(i);
-        }
-        return result;
-    }
-
-    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
-    public static String bytesToHex(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        char[] hexChars = new char[bytes.length * 2];
-        for ( int j = 0; j < bytes.length; j++ ) {
-            int v = bytes[j] & 0xFF;
-            hexChars[j * 2] = hexArray[v >>> 4];
-            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
-        }
-        return new String(hexChars);
-    }
-}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 03da5b2..2bd55e2 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -158,8 +158,8 @@
         }
 
         @Override
-        public void onCleanupUser(int userHandle) {
-            mService.onCleanupUser(userHandle);
+        public void onStopUser(int userHandle) {
+            mService.onStopUser(userHandle);
         }
     }
 
@@ -1360,8 +1360,8 @@
     }
 
 
-    private void onCleanupUser(int userId) {
-        Log.i(TAG, "onCleanupUser " + userId);
+    private void onStopUser(int userId) {
+        Log.i(TAG, "onStopUser " + userId);
         UserAccounts accounts;
         synchronized (mUsers) {
             accounts = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index a5615a9..1ed46a0 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -622,6 +622,17 @@
                             != ActivityManager.APP_START_MODE_NORMAL) {
                         if (stopping == null) {
                             stopping = new ArrayList<>();
+                            String compName = service.name.flattenToShortString();
+                            EventLogTags.writeAmStopIdleService(service.appInfo.uid, compName);
+                            StringBuilder sb = new StringBuilder(64);
+                            sb.append("Stopping service due to app idle: ");
+                            UserHandle.formatUid(sb, service.appInfo.uid);
+                            sb.append(" ");
+                            TimeUtils.formatDuration(service.createTime
+                                    - SystemClock.elapsedRealtime(), sb);
+                            sb.append(" ");
+                            sb.append(compName);
+                            Slog.w(TAG, sb.toString());
                             stopping.add(service);
                         }
                     }
@@ -1364,7 +1375,7 @@
                 // This could have made the service more important.
                 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
                         || s.app.treatLikeActivity, b.client);
-                mAm.updateOomAdjLocked(s.app);
+                mAm.updateOomAdjLocked(s.app, true);
             }
 
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
@@ -1479,13 +1490,15 @@
                                 r.binding.service.app.hasClientActivities
                                 || r.binding.service.app.treatLikeActivity, null);
                     }
-                    mAm.updateOomAdjLocked(r.binding.service.app);
+                    mAm.updateOomAdjLocked(r.binding.service.app, false);
                 }
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
 
+        mAm.updateOomAdjLocked();
+
         return true;
     }
 
@@ -2225,7 +2238,7 @@
             bumpServiceExecutingLocked(r, execInFg, "start");
             if (!oomAdjusted) {
                 oomAdjusted = true;
-                mAm.updateOomAdjLocked(r.app);
+                mAm.updateOomAdjLocked(r.app, true);
             }
             if (r.fgRequired && !r.fgWaiting) {
                 if (!r.isForeground) {
@@ -2349,7 +2362,7 @@
                 if (ibr.hasBound) {
                     try {
                         bumpServiceExecutingLocked(r, false, "bring down unbind");
-                        mAm.updateOomAdjLocked(r.app);
+                        mAm.updateOomAdjLocked(r.app, true);
                         ibr.hasBound = false;
                         ibr.requested = false;
                         r.app.thread.scheduleUnbindService(r,
@@ -2441,7 +2454,7 @@
                     bumpServiceExecutingLocked(r, false, "destroy");
                     mDestroyingServices.add(r);
                     r.destroying = true;
-                    mAm.updateOomAdjLocked(r.app);
+                    mAm.updateOomAdjLocked(r.app, true);
                     r.app.thread.scheduleStopService(r);
                 } catch (Exception e) {
                     Slog.w(TAG, "Exception when destroying service "
@@ -2542,7 +2555,7 @@
                         // it to go down there and we want it to start out near the top.
                         mAm.updateLruProcessLocked(s.app, false, null);
                     }
-                    mAm.updateOomAdjLocked(s.app);
+                    mAm.updateOomAdjLocked(s.app, true);
                     b.intent.hasBound = false;
                     // Assume the client doesn't want to know about a rebind;
                     // we will deal with that later if it asks for one.
@@ -2695,7 +2708,7 @@
                     mDestroyingServices.remove(r);
                     r.bindings.clear();
                 }
-                mAm.updateOomAdjLocked(r.app);
+                mAm.updateOomAdjLocked(r.app, true);
             }
             r.executeFg = false;
             if (r.tracker != null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b1bcbaa..c6699b6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -812,15 +812,28 @@
     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
 
     /**
-     * All of the processes that have been forced to be foreground.  The key
+     * All of the processes that have been forced to be important.  The key
      * is the pid of the caller who requested it (we hold a death
      * link on it).
      */
-    abstract class ForegroundToken implements IBinder.DeathRecipient {
-        int pid;
-        IBinder token;
+    abstract class ImportanceToken implements IBinder.DeathRecipient {
+        final int pid;
+        final IBinder token;
+        final String reason;
+
+        ImportanceToken(int _pid, IBinder _token, String _reason) {
+            pid = _pid;
+            token = _token;
+            reason = _reason;
+        }
+
+        @Override
+        public String toString() {
+            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
+                    + " " + reason + " " + pid + " " + token + " }";
+        }
     }
-    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
+    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
 
     /**
      * List of records for processes that someone had tried to start before the
@@ -2875,7 +2888,10 @@
             // The activity manager only throws security exceptions, so let's
             // log all others.
             if (!(e instanceof SecurityException)) {
-                Slog.wtf(TAG, "Activity Manager Crash", e);
+                Slog.wtf(TAG, "Activity Manager Crash."
+                        + " UID:" + Binder.getCallingUid()
+                        + " PID:" + Binder.getCallingPid()
+                        + " TRANS:" + code, e);
             }
             throw e;
         }
@@ -6479,6 +6495,7 @@
                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                         "No more processes in " + old.uidRecord);
                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
+                EventLogTags.writeAmUidStopped(uid);
                 mActiveUids.remove(uid);
                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
             }
@@ -6510,6 +6527,7 @@
             }
             uidRec.updateHasInternetPermission();
             mActiveUids.put(proc.uid, uidRec);
+            EventLogTags.writeAmUidRunning(uidRec.uid);
             noteUidProcessState(uidRec.uid, uidRec.curProcState);
             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
         }
@@ -6697,7 +6715,7 @@
         app.makeActive(thread, mProcessStats);
         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
-        app.forcingToForeground = null;
+        app.forcingToImportant = null;
         updateProcessForegroundLocked(app, false, false);
         app.hasShownUi = false;
         app.debugging = false;
@@ -6910,7 +6928,7 @@
         }
 
         // Check whether the next backup agent is in this process...
-        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
+        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                     "New app is backup target, launching agent for " + app);
             notifyPackageUse(mBackupTarget.appInfo.packageName,
@@ -7697,20 +7715,20 @@
         }
     }
 
-    void foregroundTokenDied(ForegroundToken token) {
+    void importanceTokenDied(ImportanceToken token) {
         synchronized (ActivityManagerService.this) {
             synchronized (mPidsSelfLocked) {
-                ForegroundToken cur
-                    = mForegroundProcesses.get(token.pid);
+                ImportanceToken cur
+                    = mImportantProcesses.get(token.pid);
                 if (cur != token) {
                     return;
                 }
-                mForegroundProcesses.remove(token.pid);
+                mImportantProcesses.remove(token.pid);
                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
                 if (pr == null) {
                     return;
                 }
-                pr.forcingToForeground = null;
+                pr.forcingToImportant = null;
                 updateProcessForegroundLocked(pr, false, false);
             }
             updateOomAdjLocked();
@@ -7718,9 +7736,9 @@
     }
 
     @Override
-    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
+    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
-                "setProcessForeground()");
+                "setProcessImportant()");
         synchronized(this) {
             boolean changed = false;
 
@@ -7730,28 +7748,26 @@
                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
                     return;
                 }
-                ForegroundToken oldToken = mForegroundProcesses.get(pid);
+                ImportanceToken oldToken = mImportantProcesses.get(pid);
                 if (oldToken != null) {
                     oldToken.token.unlinkToDeath(oldToken, 0);
-                    mForegroundProcesses.remove(pid);
+                    mImportantProcesses.remove(pid);
                     if (pr != null) {
-                        pr.forcingToForeground = null;
+                        pr.forcingToImportant = null;
                     }
                     changed = true;
                 }
                 if (isForeground && token != null) {
-                    ForegroundToken newToken = new ForegroundToken() {
+                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
                         @Override
                         public void binderDied() {
-                            foregroundTokenDied(this);
+                            importanceTokenDied(this);
                         }
                     };
-                    newToken.pid = pid;
-                    newToken.token = token;
                     try {
                         token.linkToDeath(newToken, 0);
-                        mForegroundProcesses.put(pid, newToken);
-                        pr.forcingToForeground = token;
+                        mImportantProcesses.put(pid, newToken);
+                        pr.forcingToImportant = newToken;
                         changed = true;
                     } catch (RemoteException e) {
                         // If the process died while doing this, we will later
@@ -11293,7 +11309,7 @@
 
                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
                 final int verifiedAdj = cpr.proc.verifiedAdj;
-                boolean success = updateOomAdjLocked(cpr.proc);
+                boolean success = updateOomAdjLocked(cpr.proc, true);
                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
                 // if the process has been successfully adjusted.  So to reduce races with
                 // it, we will check whether the process still exists.  Note that this doesn't
@@ -11755,7 +11771,7 @@
                         dst.proc = r;
                         dst.notifyAll();
                     }
-                    updateOomAdjLocked(r);
+                    updateOomAdjLocked(r, true);
                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
                             src.info.authority);
                 }
@@ -13480,7 +13496,7 @@
                     }
                 }
                 if (changed) {
-                    updateOomAdjLocked(pr);
+                    updateOomAdjLocked(pr, true);
                 }
             }
         } finally {
@@ -15465,12 +15481,12 @@
             }
         }
 
-        if (mForegroundProcesses.size() > 0) {
+        if (mImportantProcesses.size() > 0) {
             synchronized (mPidsSelfLocked) {
                 boolean printed = false;
-                for (int i=0; i<mForegroundProcesses.size(); i++) {
+                for (int i = 0; i< mImportantProcesses.size(); i++) {
                     ProcessRecord r = mPidsSelfLocked.get(
-                            mForegroundProcesses.valueAt(i).pid);
+                            mImportantProcesses.valueAt(i).pid);
                     if (dumpPackage != null && (r == null
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
@@ -15482,8 +15498,8 @@
                         printed = true;
                         printedAnything = true;
                     }
-                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
-                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
+                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
+                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
                 }
             }
         }
@@ -17754,7 +17770,7 @@
         app.unlinkDeathRecipient();
         app.makeInactive(mProcessStats);
         app.waitingToKill = null;
-        app.forcingToForeground = null;
+        app.forcingToImportant = null;
         updateProcessForegroundLocked(app, false, false);
         app.foregroundActivities = false;
         app.hasShownUi = false;
@@ -18254,7 +18270,7 @@
             mBackupAppName = app.packageName;
 
             // Try not to kill the process during backup
-            updateOomAdjLocked(proc);
+            updateOomAdjLocked(proc, true);
 
             // If the process is already attached, schedule the creation of the backup agent now.
             // If it is not yet live, this will be done when it attaches to the framework.
@@ -18351,7 +18367,7 @@
 
                 // Not backing this app up any more; reset its OOM adjustment
                 final ProcessRecord proc = mBackupTarget.app;
-                updateOomAdjLocked(proc);
+                updateOomAdjLocked(proc, true);
                 proc.inFullBackup = false;
 
                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
@@ -20749,14 +20765,6 @@
                 app.cached = false;
                 app.adjType = "fg-service";
                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
-            } else if (app.forcingToForeground != null) {
-                // The user is aware of this app, so make it visible.
-                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
-                app.cached = false;
-                app.adjType = "force-fg";
-                app.adjSource = app.forcingToForeground;
-                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
             } else if (app.hasOverlayUi) {
                 // The process is display an overlay UI.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
@@ -20767,6 +20775,21 @@
             }
         }
 
+        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
+                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
+            if (app.forcingToImportant != null) {
+                // This is currently used for toasts...  they are not interactive, and
+                // we don't want them to cause the app to become fully foreground (and
+                // thus out of background check), so we yes the best background level we can.
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+                app.cached = false;
+                app.adjType = "force-imp";
+                app.adjSource = app.forcingToImportant;
+                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+            }
+        }
+
         if (app == mHeavyWeightProcess) {
             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                 // We don't want to kill the current heavy-weight process.
@@ -22007,10 +22030,7 @@
                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
             }
         } else {
-            // If the app was being forced to the foreground, by say a Toast, then
-            // no need to treat it as an interaction
-            isInteraction = app.forcingToForeground == null
-                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
             app.fgInteractionTime = 0;
         }
         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
@@ -22111,7 +22131,14 @@
         return act;
     }
 
-    final boolean updateOomAdjLocked(ProcessRecord app) {
+    /**
+     * Update OomAdj for a specific process.
+     * @param app The process to update
+     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
+     *                  if necessary, or skip.
+     * @return whether updateOomAdjLocked(app) was successful.
+     */
+    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
         final boolean wasCached = app.cached;
@@ -22126,7 +22153,8 @@
                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
                 SystemClock.uptimeMillis());
-        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
+        if (oomAdjAll
+                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
             // Changed to/from cached state, so apps after it in the LRU
             // list may also be changed.
             updateOomAdjLocked();
@@ -22540,6 +22568,7 @@
                 } else {
                     if (uidRec.idle) {
                         uidChange = UidRecord.CHANGE_ACTIVE;
+                        EventLogTags.writeAmUidActive(uidRec.uid);
                         uidRec.idle = false;
                     }
                     uidRec.lastBackgroundTime = 0;
@@ -22618,6 +22647,7 @@
                         if (UserHandle.getAppId(uidRec.uid) == appId) {
                             if (userId == UserHandle.USER_ALL ||
                                     userId == UserHandle.getUserId(uidRec.uid)) {
+                                EventLogTags.writeAmUidIdle(uidRec.uid);
                                 uidRec.idle = true;
                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
                                         + " from package " + packageName + " user " + userId);
@@ -22652,6 +22682,7 @@
                 final long bgTime = uidRec.lastBackgroundTime;
                 if (bgTime > 0 && !uidRec.idle) {
                     if (bgTime <= maxBgTime) {
+                        EventLogTags.writeAmUidIdle(uidRec.uid);
                         uidRec.idle = true;
                         doStopUidLocked(uidRec.uid, uidRec);
                     } else {
@@ -23704,7 +23735,7 @@
                 }
                 pr.hasOverlayUi = hasOverlayUi;
                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
-                updateOomAdjLocked(pr);
+                updateOomAdjLocked(pr, true);
             }
         }
 
@@ -23842,6 +23873,34 @@
         }
     }
 
+    public void waitForBroadcastIdle(PrintWriter pw) {
+        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
+        while (true) {
+            boolean idle = true;
+            synchronized (this) {
+                for (BroadcastQueue queue : mBroadcastQueues) {
+                    if (!queue.isIdle()) {
+                        final String msg = "Waiting for queue " + queue + " to become idle...";
+                        pw.println(msg);
+                        pw.flush();
+                        Slog.v(TAG, msg);
+                        idle = false;
+                    }
+                }
+            }
+
+            if (idle) {
+                final String msg = "All broadcast queues are idle!";
+                pw.println(msg);
+                pw.flush();
+                Slog.v(TAG, msg);
+                return;
+            } else {
+                SystemClock.sleep(1000);
+            }
+        }
+    }
+
     /**
      * Return the user id of the last resumed activity.
      */
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index b6bfb00..dab122f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -251,6 +251,8 @@
                     return runUpdateApplicationInfo(pw);
                 case "no-home-screen":
                     return runNoHomeScreen(pw);
+                case "wait-for-broadcast-idle":
+                    return runWaitForBroadcastIdle(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -2419,6 +2421,11 @@
         return 0;
     }
 
+    int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
+        mInternal.waitForBroadcastIdle(pw);
+        return 0;
+    }
+
     private Resources getResources(PrintWriter pw) throws RemoteException {
         // system resources does not contain all the device configuration, construct it manually.
         Configuration config = mInterface.getConfiguration();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index ba2c0cd..5c57be2 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -131,6 +131,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
@@ -249,6 +250,8 @@
     // Last configuration reported to the activity in the client process.
     private MergedConfiguration mLastReportedConfiguration;
     private int mLastReportedDisplayId;
+    private boolean mLastReportedMultiWindowMode;
+    private boolean mLastReportedPictureInPictureMode;
     CompatibilityInfo compat;// last used compatibility mode
     ActivityRecord resultTo; // who started this entry, so will get our reply
     final String resultWho; // additional identifier for use by resultTo.
@@ -289,10 +292,6 @@
     boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
     boolean immersive;      // immersive mode (don't interrupt if possible)
     boolean forceNewConfig; // force re-create with new config next time
-    private boolean mInMultiWindowMode; // whether or not this activity is currently in multi-window
-                                        // mode (default false)
-    private boolean mInPictureInPictureMode; // whether or not this activity is currently in
-                                             // picture-in-picture mode (default false)
     boolean supportsPictureInPictureWhilePausing;  // This flag is set by the system to indicate
         // that the activity can enter picture in picture while pausing (ie. only when another
         // task is brought to front or started)
@@ -535,6 +534,8 @@
         }
         if (info != null) {
             pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
+            pw.println(prefix + "mLastReportedMultiWindowMode=" + mLastReportedMultiWindowMode
+                    + " mLastReportedPictureInPictureMode=" + mLastReportedPictureInPictureMode);
             if (info.supportsPictureInPicture()) {
                 pw.println(prefix + "supportsPictureInPicture=" + info.supportsPictureInPicture());
                 pw.println(prefix + "supportsPictureInPictureWhilePausing: "
@@ -637,15 +638,15 @@
 
         // An activity is considered to be in multi-window mode if its task isn't fullscreen.
         final boolean inMultiWindowMode = !task.mFullscreen;
-        if (inMultiWindowMode != mInMultiWindowMode) {
-            mInMultiWindowMode = inMultiWindowMode;
+        if (inMultiWindowMode != mLastReportedMultiWindowMode) {
+            mLastReportedMultiWindowMode = inMultiWindowMode;
             scheduleMultiWindowModeChanged(getConfiguration());
         }
     }
 
     private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
         try {
-            app.thread.scheduleMultiWindowModeChanged(appToken, mInMultiWindowMode,
+            app.thread.scheduleMultiWindowModeChanged(appToken, mLastReportedMultiWindowMode,
                     overrideConfig);
         } catch (Exception e) {
             // If process died, I don't care.
@@ -659,11 +660,11 @@
 
         final boolean inPictureInPictureMode = (task.getStackId() == PINNED_STACK_ID) &&
                 (targetStackBounds != null);
-        if (inPictureInPictureMode != mInPictureInPictureMode) {
+        if (inPictureInPictureMode != mLastReportedPictureInPictureMode) {
             // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
             // update that here in order
-            mInPictureInPictureMode = inPictureInPictureMode;
-            mInMultiWindowMode = inPictureInPictureMode;
+            mLastReportedPictureInPictureMode = inPictureInPictureMode;
+            mLastReportedMultiWindowMode = inPictureInPictureMode;
             final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
                     targetStackBounds, null);
             schedulePictureInPictureModeChanged(newConfig);
@@ -673,7 +674,8 @@
 
     private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
         try {
-            app.thread.schedulePictureInPictureModeChanged(appToken, mInPictureInPictureMode,
+            app.thread.schedulePictureInPictureModeChanged(appToken,
+                    mLastReportedPictureInPictureMode,
                     overrideConfig);
         } catch (Exception e) {
             // If process died, no one cares.
@@ -891,15 +893,7 @@
 
         Entry ent = AttributeCache.instance().get(packageName,
                 realTheme, com.android.internal.R.styleable.Window, userId);
-        final boolean translucent = ent != null && (ent.array.getBoolean(
-                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
-                || (!ent.array.hasValue(
-                        com.android.internal.R.styleable.Window_windowIsTranslucent)
-                        && ent.array.getBoolean(
-                                com.android.internal.R.styleable.Window_windowSwipeToDismiss,
-                                        false)));
-        fullscreen = ent != null && !ent.array.getBoolean(
-                com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
+        fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
         noDisplay = ent != null && ent.array.getBoolean(
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
 
@@ -940,6 +934,12 @@
 
         task.addActivityToTop(this);
 
+        // When an activity is started directly into a split-screen fullscreen stack, we need to
+        // update the initial multi-window modes so that the callbacks are scheduled correctly when
+        // the user leaves that mode.
+        mLastReportedMultiWindowMode = !task.mFullscreen;
+        mLastReportedPictureInPictureMode = (task.getStackId() == PINNED_STACK_ID);
+
         onOverrideConfigurationSent();
     }
 
@@ -2167,9 +2167,7 @@
     }
 
     void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
-        if (state == INITIALIZING
-                && mStartingWindowState == STARTING_WINDOW_SHOWN
-                && behindFullscreenActivity) {
+        if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
             if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
             mStartingWindowState = STARTING_WINDOW_REMOVED;
             mWindowContainerController.removeStartingWindow();
@@ -2181,6 +2179,11 @@
     }
 
     void setRequestedOrientation(int requestedOrientation) {
+        if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
+                && appInfo.targetSdkVersion >= O) {
+            throw new IllegalStateException("Only fullscreen activities can request orientation");
+        }
+
         final int displayId = getDisplayId();
         final Configuration displayConfig =
                 mStackSupervisor.getDisplayOverrideConfiguration(displayId);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f49d482..5c57704 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1491,6 +1491,7 @@
 
             // This is the first time we failed -- restart process and
             // retry.
+            r.launchFailed = true;
             app.activities.remove(r);
             throw e;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index e33ae0d..6d4eb5b 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -637,7 +637,6 @@
         if (componentSpecified
                 && intent.getData() != null
                 && Intent.ACTION_VIEW.equals(intent.getAction())
-                && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
                 && mService.getPackageManagerInternalLocked()
                         .isInstantAppInstallerComponent(intent.getComponent())) {
             // intercept intents targeted directly to the ephemeral installer the
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index d6bfb35..cfb5478 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -740,6 +740,8 @@
         }
         // If we've created a crash dialog, show it without the lock held
         if(data.proc.crashDialog != null) {
+            Slog.i(TAG, "Showing crash dialog for package " + data.proc.info.packageName
+                    + " u" + data.proc.userId);
             data.proc.crashDialog.show();
         }
     }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 983c975..7a46248 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -966,6 +966,14 @@
     }
 
     @Override
+    public void noteBleScanResult(WorkSource ws) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteBluetoothScanResultFromSourceLocked(ws);
+        }
+    }
+
+    @Override
     public void noteWifiControllerActivity(WifiActivityEnergyInfo info) {
         enforceCallingPermission();
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 090234c..1705b58 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -51,7 +51,6 @@
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.TimeUtils;
-import com.android.server.DeviceIdleController;
 
 import static com.android.server.am.ActivityManagerDebugConfig.*;
 
@@ -204,6 +203,11 @@
         mDelayBehindServices = allowDelayBehindServices;
     }
 
+    @Override
+    public String toString() {
+        return mQueueName;
+    }
+
     public boolean isPendingBroadcastProcessLocked(int pid) {
         return mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid;
     }
@@ -682,7 +686,7 @@
                 // are already core system stuff so don't matter for this.
                 r.curApp = filter.receiverList.app;
                 filter.receiverList.app.curReceivers.add(r);
-                mService.updateOomAdjLocked(r.curApp);
+                mService.updateOomAdjLocked(r.curApp, true);
             }
         }
         try {
@@ -1572,6 +1576,11 @@
                 record.intent == null ? "" : record.intent.getAction());
     }
 
+    final boolean isIdle() {
+        return mParallelBroadcasts.isEmpty() && mOrderedBroadcasts.isEmpty()
+                && (mPendingBroadcast == null);
+    }
+
     final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index f618fc7..372ab6b 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -114,3 +114,14 @@
 
 # UserState has changed
 30051 am_user_state_changed (id|1|5),(state|1|5)
+
+# Note when any processes of a uid have started running
+30052 am_uid_running (UID|1|5)
+# Note when all processes of a uid have stopped.
+30053 am_uid_stopped (UID|1|5)
+# Note when the state of a uid has become active.
+30054 am_uid_active (UID|1|5)
+# Note when the state of a uid has become idle (background check enforced).
+30055 am_uid_idle (UID|1|5)
+# Note when a service is being forcibly stopped because its app went idle.
+30056 am_stop_idle_service (UID|1|5),(Component Name|3)
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index fbc2bd2..b222e3a 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -135,7 +135,7 @@
     long interactionEventTime;  // The time we sent the last interaction event
     long fgInteractionTime;     // When we became foreground for interaction purposes
     String waitingToKill;       // Process is waiting to be killed when in the bg, and reason
-    IBinder forcingToForeground;// Token that is forcing this process to be foreground
+    Object forcingToImportant;  // Token that is forcing this process to be important
     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
     int lruSeq;                 // Sequence id for identifying LRU update cycles
     CompatibilityInfo compat;   // last used compatibility mode
@@ -302,9 +302,9 @@
                     pw.print(" hasAboveClient="); pw.print(hasAboveClient);
                     pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
         }
-        if (foregroundServices || forcingToForeground != null) {
+        if (foregroundServices || forcingToImportant != null) {
             pw.print(prefix); pw.print("foregroundServices="); pw.print(foregroundServices);
-                    pw.print(" forcingToForeground="); pw.println(forcingToForeground);
+                    pw.print(" forcingToImportant="); pw.println(forcingToImportant);
         }
         if (reportedInteraction || fgInteractionTime != 0) {
             pw.print(prefix); pw.print("reportedInteraction=");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 3b5e5bc..6a310f2 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -439,7 +439,7 @@
                 }
             }
 
-            Slog.d(TAG, "Sending BOOT_COMPLETE user #" + userId);
+            Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
             // Do not report secondary users, runtime restarts or first boot/upgrade
             if (userId == UserHandle.USER_SYSTEM
                     && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
@@ -451,7 +451,14 @@
             bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
             bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-            mInjector.broadcastIntentLocked(bootIntent, null, null, 0, null, null,
+            mInjector.broadcastIntentLocked(bootIntent, null, new IIntentReceiver.Stub() {
+                @Override
+                public void performReceive(Intent intent, int resultCode, String data,
+                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
+                        throws RemoteException {
+                    Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
+                }
+            }, 0, null, null,
                     new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
                     AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
         }
diff --git a/services/core/java/com/android/server/audio/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java
index 73cbffd..125095c 100644
--- a/services/core/java/com/android/server/audio/FocusRequester.java
+++ b/services/core/java/com/android/server/audio/FocusRequester.java
@@ -322,8 +322,8 @@
                 if (mFocusLossWasNotified) {
                     fd.dispatchAudioFocusChange(focusGain, mClientId);
                 }
-                mFocusController.unduckPlayers(this);
             }
+            mFocusController.unduckPlayers(this);
             mFocusLossWasNotified = false;
         } catch (android.os.RemoteException e) {
             Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
@@ -333,6 +333,15 @@
     /**
      * Called synchronized on MediaFocusControl.mAudioFocusLock
      */
+    void handleFocusGainFromRequest(int focusRequestResult) {
+        if (focusRequestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+            mFocusController.unduckPlayers(this);
+        }
+    }
+
+    /**
+     * Called synchronized on MediaFocusControl.mAudioFocusLock
+     */
     void handleFocusLoss(int focusLoss, @Nullable final FocusRequester fr) {
         try {
             if (focusLoss != mFocusLossReceived) {
@@ -381,6 +390,8 @@
                         Log.v(TAG, "NOT dispatching " + focusChangeToString(mFocusLossReceived)
                             + " to " + mClientId + ", ducking implemented by framework");
                     }
+                    mFocusController.notifyExtPolicyFocusLoss_syncAf(
+                            toAudioFocusInfo(), false /* wasDispatched */);
                     return; // with mFocusLossWasNotified = false
                 }
 
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index f5c13c1..7d742ff 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -752,6 +752,7 @@
 
                 // push focus requester at the top of the audio focus stack
                 mFocusStack.push(nfr);
+                nfr.handleFocusGainFromRequest(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
             }
             notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(),
                     AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index e98c5b9..925dfb5 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -62,6 +62,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -147,6 +148,10 @@
         }
     }
 
+    private final static int MAX_LOG_RECORDS = 500;
+
+    private final LocalLog mLocalLog = new LocalLog(MAX_LOG_RECORDS);
+
     // used to synchronize public access to members
     private final Object mPublicSync;
     private final Context mContext;
@@ -177,6 +182,7 @@
     public Tethering(Context context, INetworkManagementService nmService,
             INetworkStatsService statsService, INetworkPolicyManager policyManager,
             Looper looper, MockableSystemProperties systemProperties) {
+        mLocalLog.log("CONSTRUCTED");
         mContext = context;
         mNMService = nmService;
         mStatsService = statsService;
@@ -980,7 +986,7 @@
         return ConnectivityManager.TETHER_ERROR_NO_ERROR;
     }
 
-    // TODO review API - maybe return ArrayList<String> here and below?
+    // TODO review API - figure out how to delete these entirely.
     public String[] getTetheredIfaces() {
         ArrayList<String> list = new ArrayList<String>();
         synchronized (mPublicSync) {
@@ -1123,19 +1129,19 @@
 
             //Add states
             mInitialState = new InitialState();
-            addState(mInitialState);
             mTetherModeAliveState = new TetherModeAliveState();
-            addState(mTetherModeAliveState);
-
             mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
-            addState(mSetIpForwardingEnabledErrorState);
             mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
-            addState(mSetIpForwardingDisabledErrorState);
             mStartTetheringErrorState = new StartTetheringErrorState();
-            addState(mStartTetheringErrorState);
             mStopTetheringErrorState = new StopTetheringErrorState();
-            addState(mStopTetheringErrorState);
             mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
+
+            addState(mInitialState);
+            addState(mTetherModeAliveState);
+            addState(mSetIpForwardingEnabledErrorState);
+            addState(mSetIpForwardingDisabledErrorState);
+            addState(mStartTetheringErrorState);
+            addState(mStopTetheringErrorState);
             addState(mSetDnsForwardersErrorState);
 
             mNotifyList = new ArrayList<>();
@@ -1143,6 +1149,29 @@
             setInitialState(mInitialState);
         }
 
+        class InitialState extends State {
+            @Override
+            public boolean processMessage(Message message) {
+                maybeLogMessage(this, message.what);
+                switch (message.what) {
+                    case EVENT_IFACE_SERVING_STATE_ACTIVE:
+                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
+                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
+                        handleInterfaceServingStateActive(message.arg1, who);
+                        transitionTo(mTetherModeAliveState);
+                        break;
+                    case EVENT_IFACE_SERVING_STATE_INACTIVE:
+                        who = (TetherInterfaceStateMachine)message.obj;
+                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
+                        handleInterfaceServingStateInactive(who);
+                        break;
+                    default:
+                        return NOT_HANDLED;
+                }
+                return HANDLED;
+            }
+        }
+
         class TetherMasterUtilState extends State {
             @Override
             public boolean processMessage(Message m) {
@@ -1163,6 +1192,7 @@
                 try {
                     mNMService.setIpForwardingEnabled(true);
                 } catch (Exception e) {
+                    mLocalLog.log("ERROR " + e);
                     transitionTo(mSetIpForwardingEnabledErrorState);
                     return false;
                 }
@@ -1175,10 +1205,12 @@
                         mNMService.stopTethering();
                         mNMService.startTethering(cfg.dhcpRanges);
                     } catch (Exception ee) {
+                        mLocalLog.log("ERROR " + ee);
                         transitionTo(mStartTetheringErrorState);
                         return false;
                     }
                 }
+                mLocalLog.log("SET master tether settings: ON");
                 return true;
             }
 
@@ -1186,16 +1218,19 @@
                 try {
                     mNMService.stopTethering();
                 } catch (Exception e) {
+                    mLocalLog.log("ERROR " + e);
                     transitionTo(mStopTetheringErrorState);
                     return false;
                 }
                 try {
                     mNMService.setIpForwardingEnabled(false);
                 } catch (Exception e) {
+                    mLocalLog.log("ERROR " + e);
                     transitionTo(mSetIpForwardingDisabledErrorState);
                     return false;
                 }
                 transitionTo(mInitialState);
+                mLocalLog.log("SET master tether settings: OFF");
                 return true;
             }
 
@@ -1319,16 +1354,15 @@
                     // TODO: remove this invocation of NetworkUtils.makeStrings().
                     dnsServers = NetworkUtils.makeStrings(dnses);
                 }
-                if (VDBG) {
-                    Log.d(TAG, "Setting DNS forwarders: Network=" + network +
-                           ", dnsServers=" + Arrays.toString(dnsServers));
-                }
                 try {
                     mNMService.setDnsForwarders(network, dnsServers);
+                    mLocalLog.log(String.format(
+                            "SET DNS forwarders: network=%s dnsServers=[%s]",
+                            network, Arrays.toString(dnsServers)));
                 } catch (Exception e) {
                     // TODO: Investigate how this can fail and what exactly
                     // happens if/when such failures occur.
-                    Log.e(TAG, "Setting DNS forwarders failed!");
+                    mLocalLog.log("ERROR setting DNS forwarders failed, " + e);
                     transitionTo(mSetDnsForwardersErrorState);
                 }
             }
@@ -1393,39 +1427,18 @@
             }
         }
 
-        class InitialState extends State {
-            @Override
-            public boolean processMessage(Message message) {
-                maybeLogMessage(this, message.what);
-                boolean retValue = true;
-                switch (message.what) {
-                    case EVENT_IFACE_SERVING_STATE_ACTIVE:
-                        TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
-                        if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
-                        handleInterfaceServingStateActive(message.arg1, who);
-                        transitionTo(mTetherModeAliveState);
-                        break;
-                    case EVENT_IFACE_SERVING_STATE_INACTIVE:
-                        who = (TetherInterfaceStateMachine)message.obj;
-                        if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
-                        handleInterfaceServingStateInactive(who);
-                        break;
-                    default:
-                        retValue = false;
-                        break;
-                }
-                return retValue;
-            }
-        }
-
         class TetherModeAliveState extends TetherMasterUtilState {
             boolean mUpstreamWanted = false;
             boolean mTryCell = true;
 
             @Override
             public void enter() {
-                // TODO: examine if we should check the return value.
-                turnOnMasterTetherSettings(); // may transition us out
+                // If turning on master tether settings fails, we have already
+                // transitioned to an error state; exit early.
+                if (!turnOnMasterTetherSettings()) {
+                    return;
+                }
+
                 mSimChange.startListening();
                 mUpstreamNetworkMonitor.start();
                 mOffloadController.start();
@@ -1478,14 +1491,16 @@
                         handleInterfaceServingStateInactive(who);
 
                         if (mNotifyList.isEmpty()) {
-                            turnOffMasterTetherSettings(); // transitions appropriately
-                        } else {
-                            if (DBG) {
-                                Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
-                                        " live requests:");
-                                for (TetherInterfaceStateMachine o : mNotifyList) {
-                                    Log.d(TAG, "  " + o);
-                                }
+                            // transitions appropriately
+                            turnOffMasterTetherSettings();
+                            break;
+                        }
+
+                        if (DBG) {
+                            Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() +
+                                    " live requests:");
+                            for (TetherInterfaceStateMachine o : mNotifyList) {
+                                Log.d(TAG, "  " + o);
                             }
                         }
                         // If there has been a change and an upstream is no
@@ -1699,6 +1714,12 @@
             pw.println("Upstream wanted: " + upstreamWanted());
             pw.decreaseIndent();
         }
+
+        pw.println("Log:");
+        pw.increaseIndent();
+        mLocalLog.readOnlyLocalLog().dump(fd, pw, args);
+        pw.decreaseIndent();
+
         pw.decreaseIndent();
     }
 
@@ -1715,10 +1736,8 @@
             }
         }
 
-        if (DBG) {
-            Log.d(TAG, "iface " + iface + " notified that it was in state " + state +
-                    " with error " + error);
-        }
+        mLocalLog.log(String.format("OBSERVED iface=%s state=%s error=%s",
+                iface, state, error));
 
         try {
             // Notify that we're tethering (or not) this interface.
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index 7849896..d574265 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -567,22 +567,27 @@
 
         private final TwilightManager mTwilightManager;
 
-        private Calendar mLastActivatedTime;
-
         TwilightAutoMode() {
             mTwilightManager = getLocalService(TwilightManager.class);
         }
 
         private void updateActivated(TwilightState state) {
-            boolean activate = state != null && state.isNight();
-            if (state != null && mLastActivatedTime != null) {
+            if (state == null) {
+                // If there isn't a valid TwilightState then just keep the current activated
+                // state.
+                return;
+            }
+
+            boolean activate = state.isNight();
+            final Calendar lastActivatedTime = getLastActivatedTime();
+            if (lastActivatedTime != null) {
                 final Calendar now = Calendar.getInstance();
                 final Calendar sunrise = state.sunrise();
                 final Calendar sunset = state.sunset();
 
                 // Maintain the existing activated state if within the current period.
-                if (mLastActivatedTime.before(now)
-                        && (mLastActivatedTime.after(sunrise) ^ mLastActivatedTime.after(sunset))) {
+                if (lastActivatedTime.before(now)
+                        && (lastActivatedTime.after(sunrise) ^ lastActivatedTime.after(sunset))) {
                     activate = mController.isActivated();
                 }
             }
@@ -595,7 +600,6 @@
         @Override
         public void onStart() {
             mTwilightManager.registerListener(this, mHandler);
-            mLastActivatedTime = getLastActivatedTime();
 
             // Force an update to initialize state.
             updateActivated(mTwilightManager.getLastTwilightState());
@@ -604,14 +608,10 @@
         @Override
         public void onStop() {
             mTwilightManager.unregisterListener(this);
-            mLastActivatedTime = null;
         }
 
         @Override
         public void onActivated(boolean activated) {
-            if (mIsActivated != null) {
-                mLastActivatedTime = getLastActivatedTime();
-            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 9b984c1..6f5b028 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -16,21 +16,20 @@
 
 package com.android.server.fingerprint;
 
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.MANAGE_FINGERPRINT;
 import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
 import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 
-import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.app.SynchronousUserSwitchObserver;
-import android.content.ComponentName;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -82,10 +81,10 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.LinkedList;
 
 /**
  * A service to manage multiple clients that want to access the fingerprint HAL API.
@@ -400,6 +399,10 @@
         ClientMonitor client = mCurrentClient;
         if (client != null && client.onRemoved(fingerId, groupId, remaining)) {
             removeClient(client);
+            // When the last fingerprint of a group is removed, update the authenticator id
+            if (!hasEnrolledFingerprints(groupId)) {
+                updateActiveGroup(groupId, null);
+            }
         }
         if (client instanceof InternalRemovalClient && !mUnknownFingerprints.isEmpty()) {
             cleanupUnknownFingerprints();
@@ -446,6 +449,9 @@
         ClientMonitor client = mCurrentClient;
         if (client != null && client.onEnrollResult(fingerId, groupId, remaining)) {
             removeClient(client);
+            // When enrollment finishes, update this group's authenticator id, as the HAL has
+            // already generated a new authenticator id when the new fingerprint is enrolled.
+            updateActiveGroup(groupId, null);
         }
     }
 
@@ -1382,7 +1388,8 @@
                     daemon.setActiveGroup(userId, fpDir.getAbsolutePath());
                     mCurrentUserId = userId;
                 }
-                mAuthenticatorIds.put(userId, daemon.getAuthenticatorId());
+                mAuthenticatorIds.put(userId,
+                        hasEnrolledFingerprints(userId) ? daemon.getAuthenticatorId() : 0L);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to setActiveGroup():", e);
             }
@@ -1436,7 +1443,6 @@
      */
     public long getAuthenticatorId(String opPackageName) {
         final int userId = getUserOrWorkProfileId(opPackageName, UserHandle.getCallingUserId());
-        Long authenticatorId = mAuthenticatorIds.get(userId);
-        return authenticatorId != null ? authenticatorId : 0;
+        return mAuthenticatorIds.getOrDefault(userId, 0L);
     }
 }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 4b632fe..45971f5 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1184,21 +1184,29 @@
 
     @Override
     public int getStatus(Bundle extras) {
-        if (extras != null) {
-            extras.putInt("satellites", mSvCount);
-        }
+        setLocationExtras(extras);
         return mStatus;
     }
 
-    private void updateStatus(int status, int svCount) {
-        if (status != mStatus || svCount != mSvCount) {
+    private void updateStatus(int status, int svCount, int meanCn0, int maxCn0) {
+        if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0 ) {
             mStatus = status;
             mSvCount = svCount;
-            mLocationExtras.putInt("satellites", svCount);
+            mMeanCn0 = meanCn0;
+            mMaxCn0 = maxCn0;
+            setLocationExtras(mLocationExtras);
             mStatusUpdateTime = SystemClock.elapsedRealtime();
         }
     }
 
+    private void setLocationExtras(Bundle extras) {
+        if (extras != null) {
+            extras.putInt("satellites", mSvCount);
+            extras.putInt("meanCn0", mMeanCn0);
+            extras.putInt("maxCn0", mMaxCn0);
+        }
+    }
+
     @Override
     public long getStatusUpdateTime() {
         return mStatusUpdateTime;
@@ -1449,7 +1457,7 @@
             }
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
             mFixRequestTime = System.currentTimeMillis();
             if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
                 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
@@ -1472,7 +1480,7 @@
             mLastFixTime = 0;
 
             // reset SV count to zero
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0, 0, 0);
         }
     }
 
@@ -1558,7 +1566,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.AVAILABLE, mSvCount);
+            updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
 
        if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
@@ -1622,15 +1630,21 @@
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + svCount);
         }
-        // Calculate number of sets used in fix.
+        // Calculate number of satellites used in fix.
         int usedInFixCount = 0;
+        int maxCn0 = 0;
+        int meanCn0 = 0;
         for (int i = 0; i < svCount; i++) {
             if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
                 ++usedInFixCount;
+                if (mCn0s[i] > maxCn0) {
+                    maxCn0 = (int)mCn0s[i];
+                }
+                meanCn0 += mCn0s[i];
             }
             if (VERBOSE) {
                 Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
-                        " cn0: " + mCn0s[i]/10 +
+                        " cn0: " + mCn0s[i] +
                         " elev: " + mSvElevations[i] +
                         " azimuth: " + mSvAzimuths[i] +
                         " carrier frequency: " + mSvCarrierFreqs[i] +
@@ -1644,8 +1658,11 @@
                         ? "" : "F"));
             }
         }
-        // return number of sets used in fix instead of total
-        updateStatus(mStatus, usedInFixCount);
+        if (usedInFixCount > 0) {
+            meanCn0 /= usedInFixCount;
+        }
+        // return number of sats used in fix instead of total reported
+        updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
 
         if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
             System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
@@ -1653,7 +1670,7 @@
             Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
             intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
+            updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
         }
     }
 
@@ -2531,6 +2548,8 @@
     private float mSvAzimuths[] = new float[MAX_SVS];
     private float mSvCarrierFreqs[] = new float[MAX_SVS];
     private int mSvCount;
+    private int mMeanCn0;
+    private int mMaxCn0;
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
new file mode 100644
index 0000000..6b8a74f
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -0,0 +1,2261 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.locksettings;
+
+import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
+import static android.Manifest.permission.READ_CONTACTS;
+import static android.content.Context.KEYGUARD_SERVICE;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.PasswordMetrics;
+import android.app.backup.BackupManager;
+import android.app.trust.IStrongAuthTracker;
+import android.app.trust.TrustManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.StrictMode;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.provider.Settings.SettingNotFoundException;
+import android.security.GateKeeper;
+import android.security.KeyStore;
+import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.widget.ICheckCredentialProgressCallback;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.SystemService;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+
+import libcore.util.HexEncoding;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+/**
+ * Keeps the lock pattern/password data and related settings for each user. Used by
+ * LockPatternUtils. Needs to be a service because Settings app also needs to be able to save
+ * lockscreen information for secondary users.
+ *
+ * @hide
+ */
+public class LockSettingsService extends ILockSettings.Stub {
+    private static final String TAG = "LockSettingsService";
+    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
+    private static final boolean DEBUG = false;
+
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+
+    private final Object mSeparateChallengeLock = new Object();
+
+    private final Injector mInjector;
+    private final Context mContext;
+    private final Handler mHandler;
+    @VisibleForTesting
+    protected final LockSettingsStorage mStorage;
+    private final LockSettingsStrongAuth mStrongAuth;
+    private final SynchronizedStrongAuthTracker mStrongAuthTracker;
+
+    private final LockPatternUtils mLockPatternUtils;
+    private final NotificationManager mNotificationManager;
+    private final UserManager mUserManager;
+    private final IActivityManager mActivityManager;
+
+    private final KeyStore mKeyStore;
+
+    private boolean mFirstCallToVold;
+    protected IGateKeeperService mGateKeeperService;
+    private SyntheticPasswordManager mSpManager;
+
+    /**
+     * The UIDs that are used for system credential storage in keystore.
+     */
+    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
+            Process.WIFI_UID, Process.VPN_UID,
+            Process.ROOT_UID };
+
+    // This class manages life cycle events for encrypted users on File Based Encryption (FBE)
+    // devices. The most basic of these is to show/hide notifications about missing features until
+    // the user unlocks the account and credential-encrypted storage is available.
+    public static final class Lifecycle extends SystemService {
+        private LockSettingsService mLockSettingsService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            AndroidKeyStoreProvider.install();
+            mLockSettingsService = new LockSettingsService(getContext());
+            publishBinderService("lock_settings", mLockSettingsService);
+        }
+
+        @Override
+        public void onStartUser(int userHandle) {
+            mLockSettingsService.onStartUser(userHandle);
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mLockSettingsService.onUnlockUser(userHandle);
+        }
+
+        @Override
+        public void onCleanupUser(int userHandle) {
+            mLockSettingsService.onCleanupUser(userHandle);
+        }
+    }
+
+    @VisibleForTesting
+    protected static class SynchronizedStrongAuthTracker
+            extends LockPatternUtils.StrongAuthTracker {
+        public SynchronizedStrongAuthTracker(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void handleStrongAuthRequiredChanged(int strongAuthFlags, int userId) {
+            synchronized (this) {
+                super.handleStrongAuthRequiredChanged(strongAuthFlags, userId);
+            }
+        }
+
+        @Override
+        public int getStrongAuthForUser(int userId) {
+            synchronized (this) {
+                return super.getStrongAuthForUser(userId);
+            }
+        }
+
+        void register(LockSettingsStrongAuth strongAuth) {
+            strongAuth.registerStrongAuthTracker(this.mStub);
+        }
+    }
+
+    /**
+     * Tie managed profile to primary profile if it is in unified mode and not tied before.
+     *
+     * @param managedUserId Managed profile user Id
+     * @param managedUserPassword Managed profile original password (when it has separated lock).
+     *            NULL when it does not have a separated lock before.
+     */
+    public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) {
+        if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId);
+        // Only for managed profile
+        if (!mUserManager.getUserInfo(managedUserId).isManagedProfile()) {
+            return;
+        }
+        // Do not tie managed profile when work challenge is enabled
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+            return;
+        }
+        // Do not tie managed profile to parent when it's done already
+        if (mStorage.hasChildProfileLock(managedUserId)) {
+            return;
+        }
+        // Do not tie it to parent when parent does not have a screen lock
+        final int parentId = mUserManager.getProfileParent(managedUserId).id;
+        if (!isUserSecure(parentId)) {
+            if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock");
+            return;
+        }
+        // Do not tie when the parent has no SID (but does have a screen lock).
+        // This can only happen during an upgrade path where SID is yet to be
+        // generated when the user unlocks for the first time.
+        try {
+            if (getGateKeeperService().getSecureUserId(parentId) == 0) {
+                return;
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to talk to GateKeeper service", e);
+            return;
+        }
+        if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!");
+        byte[] randomLockSeed = new byte[] {};
+        try {
+            randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
+            String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
+            setLockCredentialInternal(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    managedUserPassword, managedUserId);
+            // We store a private credential for the managed user that's unlocked by the primary
+            // account holder's credential. As such, the user will never be prompted to enter this
+            // password directly, so we always store a password.
+            setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                    DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
+            tieProfileLockToParent(managedUserId, newPassword);
+        } catch (NoSuchAlgorithmException | RemoteException e) {
+            Slog.e(TAG, "Fail to tie managed profile", e);
+            // Nothing client can do to fix this issue, so we do not throw exception out
+        }
+    }
+
+    static class Injector {
+
+        protected Context mContext;
+
+        public Injector(Context context) {
+            mContext = context;
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public Handler getHandler() {
+            return new Handler();
+        }
+
+        public LockSettingsStorage getStorage() {
+            final LockSettingsStorage storage = new LockSettingsStorage(mContext);
+            storage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                @Override
+                public void initialize(SQLiteDatabase db) {
+                    // Get the lockscreen default from a system property, if available
+                    boolean lockScreenDisable = SystemProperties.getBoolean(
+                            "ro.lockscreen.disable.default", false);
+                    if (lockScreenDisable) {
+                        storage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
+                    }
+                }
+            });
+            return storage;
+        }
+
+        public LockSettingsStrongAuth getStrongAuth() {
+            return new LockSettingsStrongAuth(mContext);
+        }
+
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return new SynchronizedStrongAuthTracker(mContext);
+        }
+
+        public IActivityManager getActivityManager() {
+            return ActivityManager.getService();
+        }
+
+        public LockPatternUtils getLockPatternUtils() {
+            return new LockPatternUtils(mContext);
+        }
+
+        public NotificationManager getNotificationManager() {
+            return (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+
+        public UserManager getUserManager() {
+            return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        }
+
+        public DevicePolicyManager getDevicePolicyManager() {
+            return (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        }
+
+        public KeyStore getKeyStore() {
+            return KeyStore.getInstance();
+        }
+
+        public IStorageManager getStorageManager() {
+            final IBinder service = ServiceManager.getService("mount");
+            if (service != null) {
+                return IStorageManager.Stub.asInterface(service);
+            }
+            return null;
+        }
+
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return new SyntheticPasswordManager(storage);
+        }
+
+        public int binderGetCallingUid() {
+            return Binder.getCallingUid();
+        }
+    }
+
+    public LockSettingsService(Context context) {
+        this(new Injector(context));
+    }
+
+    @VisibleForTesting
+    protected LockSettingsService(Injector injector) {
+        mInjector = injector;
+        mContext = injector.getContext();
+        mKeyStore = injector.getKeyStore();
+        mHandler = injector.getHandler();
+        mStrongAuth = injector.getStrongAuth();
+        mActivityManager = injector.getActivityManager();
+
+        mLockPatternUtils = injector.getLockPatternUtils();
+        mFirstCallToVold = true;
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_ADDED);
+        filter.addAction(Intent.ACTION_USER_STARTING);
+        filter.addAction(Intent.ACTION_USER_REMOVED);
+        injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
+                null, null);
+
+        mStorage = injector.getStorage();
+        mNotificationManager = injector.getNotificationManager();
+        mUserManager = injector.getUserManager();
+        mStrongAuthTracker = injector.getStrongAuthTracker();
+        mStrongAuthTracker.register(mStrongAuth);
+
+        mSpManager = injector.getSyntheticPasswordManager(mStorage);
+    }
+
+    /**
+     * If the account is credential-encrypted, show notification requesting the user to unlock the
+     * device.
+     */
+    private void maybeShowEncryptionNotificationForUser(@UserIdInt int userId) {
+        final UserInfo user = mUserManager.getUserInfo(userId);
+        if (!user.isManagedProfile()) {
+            // When the user is locked, we communicate it loud-and-clear
+            // on the lockscreen; we only show a notification below for
+            // locked managed profiles.
+            return;
+        }
+
+        final UserHandle userHandle = user.getUserHandle();
+        final boolean isSecure = isUserSecure(userId);
+        if (isSecure && !mUserManager.isUserUnlockingOrUnlocked(userHandle)) {
+            UserInfo parent = mUserManager.getProfileParent(userId);
+            if (parent != null &&
+                    mUserManager.isUserUnlockingOrUnlocked(parent.getUserHandle()) &&
+                    !mUserManager.isQuietModeEnabled(userHandle)) {
+                // Only show notifications for managed profiles once their parent
+                // user is unlocked.
+                showEncryptionNotificationForProfile(userHandle);
+            }
+        }
+    }
+
+    private void showEncryptionNotificationForProfile(UserHandle user) {
+        Resources r = mContext.getResources();
+        CharSequence title = r.getText(
+                com.android.internal.R.string.user_encrypted_title);
+        CharSequence message = r.getText(
+                com.android.internal.R.string.profile_encrypted_message);
+        CharSequence detail = r.getText(
+                com.android.internal.R.string.profile_encrypted_detail);
+
+        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
+        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null,
+                user.getIdentifier());
+        if (unlockIntent == null) {
+            return;
+        }
+        unlockIntent.setFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        showEncryptionNotification(user, title, message, detail, intent);
+    }
+
+    private void showEncryptionNotification(UserHandle user, CharSequence title,
+            CharSequence message, CharSequence detail, PendingIntent intent) {
+        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
+
+        // Suppress all notifications on non-FBE devices for now
+        if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
+
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setSubText(detail)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setContentIntent(intent)
+                        .build();
+        mNotificationManager.notifyAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            notification, user);
+    }
+
+    private void hideEncryptionNotification(UserHandle userHandle) {
+        if (DEBUG) Slog.v(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
+        mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
+            userHandle);
+    }
+
+    public void onCleanupUser(int userId) {
+        hideEncryptionNotification(new UserHandle(userId));
+    }
+
+    public void onStartUser(final int userId) {
+        maybeShowEncryptionNotificationForUser(userId);
+    }
+
+    public void onUnlockUser(final int userId) {
+        // Perform tasks which require locks in LSS on a handler, as we are callbacks from
+        // ActivityManager.unlockUser()
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Hide notification first, as tie managed profile lock takes time
+                hideEncryptionNotification(new UserHandle(userId));
+
+                // Now we have unlocked the parent user we should show notifications
+                // about any profiles that exist.
+                List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (int i = 0; i < profiles.size(); i++) {
+                    UserInfo profile = profiles.get(i);
+                    final boolean isSecure = isUserSecure(profile.id);
+                    if (isSecure && profile.isManagedProfile()) {
+                        UserHandle userHandle = profile.getUserHandle();
+                        if (!mUserManager.isUserUnlockingOrUnlocked(userHandle) &&
+                                !mUserManager.isQuietModeEnabled(userHandle)) {
+                            showEncryptionNotificationForProfile(userHandle);
+                        }
+                    }
+                }
+
+                if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                    tieManagedProfileLockIfNecessary(userId, null);
+                }
+            }
+        });
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
+                // Notify keystore that a new user was added.
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > UserHandle.USER_SYSTEM) {
+                    removeUser(userHandle, /* unknownUser= */ true);
+                }
+                final KeyStore ks = KeyStore.getInstance();
+                final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
+                final int parentHandle = parentInfo != null ? parentInfo.id : -1;
+                ks.onUserAdded(userHandle, parentHandle);
+            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                mStorage.prefetchUser(userHandle);
+            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                if (userHandle > 0) {
+                    removeUser(userHandle, /* unknownUser= */ false);
+                }
+            }
+        }
+    };
+
+    @Override // binder interface
+    public void systemReady() {
+        migrateOldData();
+        try {
+            getGateKeeperService();
+            mSpManager.initWeaverService();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failure retrieving IGateKeeperService", e);
+        }
+        // TODO: maybe skip this for split system user mode.
+        mStorage.prefetchUser(UserHandle.USER_SYSTEM);
+    }
+
+    private void migrateOldData() {
+        try {
+            // These Settings moved before multi-user was enabled, so we only have to do it for the
+            // root user.
+            if (getString("migrated", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                for (String validSetting : VALID_SETTINGS) {
+                    String value = Settings.Secure.getString(cr, validSetting);
+                    if (value != null) {
+                        setString(validSetting, value, 0);
+                    }
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated", "true", 0);
+                Slog.i(TAG, "Migrated lock settings to new location");
+            }
+
+            // These Settings changed after multi-user was enabled, hence need to be moved per user.
+            if (getString("migrated_user_specific", null, 0) == null) {
+                final ContentResolver cr = mContext.getContentResolver();
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int user = 0; user < users.size(); user++) {
+                    // Migrate owner info
+                    final int userId = users.get(user).id;
+                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
+                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
+                    if (!TextUtils.isEmpty(ownerInfo)) {
+                        setString(OWNER_INFO, ownerInfo, userId);
+                        Settings.Secure.putStringForUser(cr, OWNER_INFO, "", userId);
+                    }
+
+                    // Migrate owner info enabled. Note there was a bug where older platforms only
+                    // stored this value if the checkbox was toggled at least once. The code detects
+                    // this case by handling the exception.
+                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
+                    boolean enabled;
+                    try {
+                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
+                        enabled = ivalue != 0;
+                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
+                    } catch (SettingNotFoundException e) {
+                        // Setting was never stored. Store it if the string is not empty.
+                        if (!TextUtils.isEmpty(ownerInfo)) {
+                            setLong(OWNER_INFO_ENABLED, 1, userId);
+                        }
+                    }
+                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
+                }
+                // No need to move the password / pattern files. They're already in the right place.
+                setString("migrated_user_specific", "true", 0);
+                Slog.i(TAG, "Migrated per-user lock settings to new location");
+            }
+
+            // Migrates biometric weak such that the fallback mechanism becomes the primary.
+            if (getString("migrated_biometric_weak", null, 0) == null) {
+                List<UserInfo> users = mUserManager.getUsers();
+                for (int i = 0; i < users.size(); i++) {
+                    int userId = users.get(i).id;
+                    long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    long alternateType = getLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                    if (type == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                alternateType,
+                                userId);
+                    }
+                    setLong(LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+                            userId);
+                }
+                setString("migrated_biometric_weak", "true", 0);
+                Slog.i(TAG, "Migrated biometric weak to use the fallback instead");
+            }
+
+            // Migrates lockscreen.disabled. Prior to M, the flag was ignored when more than one
+            // user was present on the system, so if we're upgrading to M and there is more than one
+            // user we disable the flag to remain consistent.
+            if (getString("migrated_lockscreen_disabled", null, 0) == null) {
+                final List<UserInfo> users = mUserManager.getUsers();
+                final int userCount = users.size();
+                int switchableUsers = 0;
+                for (int i = 0; i < userCount; i++) {
+                    if (users.get(i).supportsSwitchTo()) {
+                        switchableUsers++;
+                    }
+                }
+
+                if (switchableUsers > 1) {
+                    for (int i = 0; i < userCount; i++) {
+                        int id = users.get(i).id;
+
+                        if (getBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id)) {
+                            setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                        }
+                    }
+                }
+
+                setString("migrated_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen disabled flag");
+            }
+
+            final List<UserInfo> users = mUserManager.getUsers();
+            for (int i = 0; i < users.size(); i++) {
+                final UserInfo userInfo = users.get(i);
+                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
+                    // When managed profile has a unified lock, the password quality stored has 2
+                    // possibilities only.
+                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
+                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
+                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
+                    // unified lock.
+                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
+                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                        // Only possible when it's upgraded from nyc dp3
+                        Slog.i(TAG, "Migrated tied profile lock type");
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
+                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
+                        // It should not happen
+                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
+                    }
+                }
+                try {
+                    final String alias = LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userInfo.id;
+                    java.security.KeyStore keyStore =
+                            java.security.KeyStore.getInstance("AndroidKeyStore");
+                    keyStore.load(null);
+                    if (keyStore.containsAlias(alias)) {
+                        keyStore.deleteEntry(alias);
+                    }
+                } catch (KeyStoreException | NoSuchAlgorithmException |
+                        CertificateException | IOException e) {
+                    Slog.e(TAG, "Unable to remove tied profile key", e);
+                }
+            }
+
+            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_WATCH);
+            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
+            // and device management the lockscreen must be re-enabled now for users that upgrade.
+            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
+                final int userCount = users.size();
+                for (int i = 0; i < userCount; i++) {
+                    int id = users.get(i).id;
+                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                }
+                setString("migrated_wear_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
+            }
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Unable to migrate old data", re);
+        }
+    }
+
+    private final void checkWritePermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
+    }
+
+    private final void checkPasswordReadPermission(int userId) {
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
+    }
+
+    private final void checkReadPermission(String requestedKey, int userId) {
+        final int callingUid = Binder.getCallingUid();
+
+        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + READ_CONTACTS + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+
+        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
+            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
+            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("uid=" + callingUid
+                        + " needs permission " + PERMISSION + " to read "
+                        + requestedKey + " for user " + userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException {
+        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
+        synchronized (mSeparateChallengeLock) {
+            return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
+        }
+    }
+
+    @Override
+    public void setSeparateProfileChallengeEnabled(int userId, boolean enabled,
+            String managedUserPassword) throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId);
+            if (enabled) {
+                mStorage.removeChildProfileLock(userId);
+                removeKeystoreProfileKey(userId);
+            } else {
+                tieManagedProfileLockIfNecessary(userId, managedUserPassword);
+            }
+        }
+    }
+
+    @Override
+    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value ? "1" : "0");
+    }
+
+    @Override
+    public void setLong(String key, long value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, Long.toString(value));
+    }
+
+    @Override
+    public void setString(String key, String value, int userId) throws RemoteException {
+        checkWritePermission(userId);
+        setStringUnchecked(key, userId, value);
+    }
+
+    private void setStringUnchecked(String key, int userId, String value) {
+        mStorage.writeKeyValue(key, value, userId);
+        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
+            BackupManager.dataChanged("com.android.providers.settings");
+        }
+    }
+
+    @Override
+    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ?
+                defaultValue : (value.equals("1") || value.equals("true"));
+    }
+
+    @Override
+    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        String value = getStringUnchecked(key, null, userId);
+        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
+    }
+
+    @Override
+    public String getString(String key, String defaultValue, int userId) throws RemoteException {
+        checkReadPermission(key, userId);
+        return getStringUnchecked(key, defaultValue, userId);
+    }
+
+    public String getStringUnchecked(String key, String defaultValue, int userId) {
+        if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0";
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
+            key = Settings.Secure.LOCK_PATTERN_ENABLED;
+        }
+
+        return mStorage.readKeyValue(key, defaultValue, userId);
+    }
+
+    @Override
+    public boolean havePassword(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPassword(userId);
+    }
+
+    @Override
+    public boolean havePattern(int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                long handle = getSyntheticPasswordHandleLocked(userId);
+                return mSpManager.getCredentialType(handle, userId) ==
+                        LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+            }
+        }
+        // Do we need a permissions check here?
+        return mStorage.hasPattern(userId);
+    }
+
+    private boolean isUserSecure(int userId) {
+        synchronized (mSpManager) {
+            try {
+                if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                    long handle = getSyntheticPasswordHandleLocked(userId);
+                    return mSpManager.getCredentialType(handle, userId) !=
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE;
+                }
+            } catch (RemoteException e) {
+                // fall through
+            }
+        }
+        return mStorage.hasCredential(userId);
+    }
+
+    private void setKeystorePassword(String password, int userHandle) {
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserPasswordChanged(userHandle, password);
+    }
+
+    private void unlockKeystore(String password, int userHandle) {
+        if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
+        final KeyStore ks = KeyStore.getInstance();
+        ks.unlock(userHandle, password);
+    }
+
+    @VisibleForTesting
+    protected String getDecryptedPasswordForTiedProfile(int userId)
+            throws KeyStoreException, UnrecoverableKeyException,
+            NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
+            CertificateException, IOException {
+        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE);
+        byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE,
+                storedData.length);
+        byte[] decryptionResult;
+        java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        SecretKey decryptionKey = (SecretKey) keyStore.getKey(
+                LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId, null);
+
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+
+        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv));
+        decryptionResult = cipher.doFinal(encryptedPassword);
+        return new String(decryptionResult, StandardCharsets.UTF_8);
+    }
+
+    private void unlockChildProfile(int profileHandle) throws RemoteException {
+        try {
+            doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            if (e instanceof FileNotFoundException) {
+                Slog.i(TAG, "Child profile key not found");
+            } else {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+    }
+
+    private void unlockUser(int userId, byte[] token, byte[] secret) {
+        // TODO: make this method fully async so we can update UI with progress strings
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IProgressListener listener = new IProgressListener.Stub() {
+            @Override
+            public void onStarted(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser started");
+            }
+
+            @Override
+            public void onProgress(int id, int progress, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser progress " + progress);
+            }
+
+            @Override
+            public void onFinished(int id, Bundle extras) throws RemoteException {
+                Log.d(TAG, "unlockUser finished");
+                latch.countDown();
+            }
+        };
+
+        try {
+            mActivityManager.unlockUser(userId, token, secret, listener);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+
+        try {
+            latch.await(15, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+        try {
+            if (!mUserManager.getUserInfo(userId).isManagedProfile()) {
+                final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+                for (UserInfo pi : profiles) {
+                    // Unlock managed profile with unified lock
+                    if (pi.isManagedProfile()
+                            && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                            && mStorage.hasChildProfileLock(pi.id)
+                            && mUserManager.isUserRunning(pi.id)) {
+                        unlockChildProfile(pi.id);
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Failed to unlock child profile", e);
+        }
+    }
+
+    private Map<Integer, String> getDecryptedPasswordsForAllTiedProfiles(int userId) {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return null;
+        }
+        Map<Integer, String> result = new ArrayMap<Integer, String>();
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (!profile.isManagedProfile()) {
+                continue;
+            }
+            final int managedUserId = profile.id;
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                continue;
+            }
+            try {
+                result.put(userId, getDecryptedPasswordForTiedProfile(userId));
+            } catch (KeyStoreException | UnrecoverableKeyException | NoSuchAlgorithmException
+                    | NoSuchPaddingException | InvalidKeyException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                // ignore
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Synchronize all profile's work challenge of the given user if it's unified: tie or clear them
+     * depending on the parent user's secure state.
+     *
+     * When clearing tied work challenges, a pre-computed password table for profiles are required,
+     * since changing password for profiles requires existing password, and existing passwords can
+     * only be computed before the parent user's password is cleared.
+     *
+     * Strictly this is a recursive function, since setLockCredentialInternal ends up calling this
+     * method again on profiles. However the recursion is guaranteed to terminate as this method
+     * terminates when the user is a managed profile.
+     */
+    private void synchronizeUnifiedWorkChallengeForProfiles(int userId,
+            Map<Integer, String> profilePasswordMap) throws RemoteException {
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            return;
+        }
+        final boolean isSecure = isUserSecure(userId);
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        final int size = profiles.size();
+        for (int i = 0; i < size; i++) {
+            final UserInfo profile = profiles.get(i);
+            if (profile.isManagedProfile()) {
+                final int managedUserId = profile.id;
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) {
+                    continue;
+                }
+                if (isSecure) {
+                    tieManagedProfileLockIfNecessary(managedUserId, null);
+                } else {
+                    // We use cached work profile password computed before clearing the parent's
+                    // credential, otherwise they get lost
+                    if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                                profilePasswordMap.get(managedUserId), managedUserId);
+                    } else {
+                        Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
+                        // Supplying null here would lead to untrusted credential change
+                        setLockCredentialInternal(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
+                                managedUserId);
+                    }
+                    mStorage.removeChildProfileLock(managedUserId);
+                    removeKeystoreProfileKey(managedUserId);
+                }
+            }
+        }
+    }
+
+    private boolean isManagedProfileWithUnifiedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    private boolean isManagedProfileWithSeparatedLock(int userId) {
+        return mUserManager.getUserInfo(userId).isManagedProfile()
+                && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
+    }
+
+    // This method should be called by LockPatternUtil only, all internal methods in this class
+    // should call setLockCredentialInternal.
+    @Override
+    public void setLockCredential(String credential, int type, String savedCredential, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        synchronized (mSeparateChallengeLock) {
+            setLockCredentialInternal(credential, type, savedCredential, userId);
+            setSeparateProfileChallengeEnabled(userId, true, null);
+            notifyPasswordChanged(userId);
+        }
+    }
+
+    private void setLockCredentialInternal(String credential, int credentialType,
+            String savedCredential, int userId) throws RemoteException {
+        // Normalize savedCredential and credential such that empty string is always represented
+        // as null.
+        if (TextUtils.isEmpty(savedCredential)) {
+            savedCredential = null;
+        }
+        if (TextUtils.isEmpty(credential)) {
+            credential = null;
+        }
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        userId);
+                return;
+            }
+        }
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            if (credential != null) {
+                Slog.wtf(TAG, "CredentialType is none, but credential is non-null.");
+            }
+            clearUserKeyProtection(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            mStorage.writeCredentialHash(CredentialHash.createEmptyHash(), userId);
+            setKeystorePassword(null, userId);
+            fixateNewestUserKeyAuth(userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            notifyActivePasswordMetricsAvailable(null, userId);
+            return;
+        }
+        if (credential == null) {
+            throw new RemoteException("Null credential with mismatched credential type");
+        }
+
+        CredentialHash currentHandle = mStorage.readCredentialHash(userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            if (savedCredential == null) {
+                try {
+                    savedCredential = getDecryptedPasswordForTiedProfile(userId);
+                } catch (FileNotFoundException e) {
+                    Slog.i(TAG, "Child profile key not found");
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        } else {
+            if (currentHandle.hash == null) {
+                if (savedCredential != null) {
+                    Slog.w(TAG, "Saved credential provided, but none stored");
+                }
+                savedCredential = null;
+            }
+        }
+        synchronized (mSpManager) {
+            if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
+                        currentHandle.type, userId);
+                spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
+                        userId);
+                return;
+            }
+        }
+        if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
+        byte[] enrolledHandle = enrollCredential(currentHandle.hash, savedCredential, credential,
+                userId);
+        if (enrolledHandle != null) {
+            CredentialHash willStore = CredentialHash.create(enrolledHandle, credentialType);
+            mStorage.writeCredentialHash(willStore, userId);
+            // push new secret and auth token to vold
+            GateKeeperResponse gkResponse = getGateKeeperService()
+                    .verifyChallenge(userId, 0, willStore.hash, credential.getBytes());
+            setUserKeyProtection(userId, credential, convertResponse(gkResponse));
+            fixateNewestUserKeyAuth(userId);
+            // Refresh the auth token
+            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+        } else {
+            throw new RemoteException("Failed to enroll " +
+                    (credentialType == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD ? "password"
+                            : "pattern"));
+        }
+    }
+
+    private VerifyCredentialResponse convertResponse(GateKeeperResponse gateKeeperResponse) {
+        VerifyCredentialResponse response;
+        int responseCode = gateKeeperResponse.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            response = new VerifyCredentialResponse(gateKeeperResponse.getTimeout());
+        } else if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            byte[] token = gateKeeperResponse.getPayload();
+            if (token == null) {
+                // something's wrong if there's no payload with a challenge
+                Slog.e(TAG, "verifyChallenge response had no associated payload");
+                response = VerifyCredentialResponse.ERROR;
+            } else {
+                response = new VerifyCredentialResponse(token);
+            }
+        } else {
+            response = VerifyCredentialResponse.ERROR;
+        }
+        return response;
+    }
+
+    @VisibleForTesting
+    protected void tieProfileLockToParent(int userId, String password) {
+        if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
+        byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8);
+        byte[] encryptionResult;
+        byte[] iv;
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            try {
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .build());
+                keyStore.setEntry(
+                        LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + userId,
+                        new java.security.KeyStore.SecretKeyEntry(secretKey),
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                                .setUserAuthenticationRequired(true)
+                                .setUserAuthenticationValidityDurationSeconds(30)
+                                .build());
+                // Key imported, obtain a reference to it.
+                SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey(
+                        LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId, null);
+                Cipher cipher = Cipher.getInstance(
+                        KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                                + KeyProperties.ENCRYPTION_PADDING_NONE);
+                cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey);
+                encryptionResult = cipher.doFinal(randomLockSeed);
+                iv = cipher.getIV();
+            } finally {
+                // The original key can now be discarded.
+                keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId);
+            }
+        } catch (CertificateException | UnrecoverableKeyException
+                | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException
+                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException("Failed to encrypt key", e);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            if (iv.length != PROFILE_KEY_IV_SIZE) {
+                throw new RuntimeException("Invalid iv length: " + iv.length);
+            }
+            outputStream.write(iv);
+            outputStream.write(encryptionResult);
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to concatenate byte arrays", e);
+        }
+        mStorage.writeChildProfileLock(userId, outputStream.toByteArray());
+    }
+
+    private byte[] enrollCredential(byte[] enrolledHandle,
+            String enrolledCredential, String toEnroll, int userId)
+            throws RemoteException {
+        checkWritePermission(userId);
+        byte[] enrolledCredentialBytes = enrolledCredential == null
+                ? null
+                : enrolledCredential.getBytes();
+        byte[] toEnrollBytes = toEnroll == null
+                ? null
+                : toEnroll.getBytes();
+        GateKeeperResponse response = getGateKeeperService().enroll(userId, enrolledHandle,
+                enrolledCredentialBytes, toEnrollBytes);
+
+        if (response == null) {
+            return null;
+        }
+
+        byte[] hash = response.getPayload();
+        if (hash != null) {
+            setKeystorePassword(toEnroll, userId);
+        } else {
+            // Should not happen
+            Slog.e(TAG, "Throttled while enrolling a password");
+        }
+        return hash;
+    }
+
+    private void setAuthlessUserKeyProtection(int userId, byte[] key) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setAuthlessUserKeyProtectiond: user=" + userId);
+        addUserKeyAuth(userId, null, key);
+    }
+
+    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setUserKeyProtection: user=" + userId);
+        if (vcr == null) {
+            throw new RemoteException("Null response verifying a credential we just set");
+        }
+        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            throw new RemoteException("Non-OK response verifying a credential we just set: "
+                    + vcr.getResponseCode());
+        }
+        byte[] token = vcr.getPayload();
+        if (token == null) {
+            throw new RemoteException("Empty payload verifying a credential we just set");
+        }
+        addUserKeyAuth(userId, token, secretFromCredential(credential));
+    }
+
+    private void clearUserKeyProtection(int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "clearUserKeyProtection user=" + userId);
+        addUserKeyAuth(userId, null, null);
+    }
+
+    private static byte[] secretFromCredential(String credential) throws RemoteException {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            // Personalize the hash
+            byte[] personalization = "Android FBE credential hash"
+                    .getBytes(StandardCharsets.UTF_8);
+            // Pad it to the block size of the hash function
+            personalization = Arrays.copyOf(personalization, 128);
+            digest.update(personalization);
+            digest.update(credential.getBytes(StandardCharsets.UTF_8));
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
+        }
+    }
+
+    private void addUserKeyAuth(int userId, byte[] token, byte[] secret)
+            throws RemoteException {
+        final UserInfo userInfo = mUserManager.getUserInfo(userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.addUserKeyAuth(userId, userInfo.serialNumber, token, secret);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    private void fixateNewestUserKeyAuth(int userId)
+            throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "fixateNewestUserKeyAuth: user=" + userId);
+        final IStorageManager storageManager = mInjector.getStorageManager();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            storageManager.fixateNewestUserKeyAuth(userId);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
+    @Override
+    public void resetKeyStore(int userId) throws RemoteException {
+        checkWritePermission(userId);
+        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+        int managedUserId = -1;
+        String managedUserDecryptedPassword = null;
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        for (UserInfo pi : profiles) {
+            // Unlock managed profile with unified lock
+            if (pi.isManagedProfile()
+                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                    && mStorage.hasChildProfileLock(pi.id)) {
+                try {
+                    if (managedUserId == -1) {
+                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
+                        managedUserId = pi.id;
+                    } else {
+                        // Should not happen
+                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
+                                + ", uid2:" + pi.id);
+                    }
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        }
+        try {
+            // Clear all the users credentials could have been installed in for this user.
+            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
+                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
+                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+                }
+            }
+        } finally {
+            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
+                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
+                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+            }
+        }
+    }
+
+    @Override
+    public VerifyCredentialResponse checkCredential(String credential, int type, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyCredential(String credential, int type, long challenge,
+            int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        return doVerifyCredential(credential, type, true, challenge, userId,
+                null /* progressCallback */);
+    }
+
+    /**
+     * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
+     * format.
+     */
+    private VerifyCredentialResponse doVerifyCredential(String credential, int credentialType,
+            boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (TextUtils.isEmpty(credential)) {
+            throw new IllegalArgumentException("Credential can't be null or empty");
+        }
+        synchronized (mSpManager) {
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
+                        credentialType, hasChallenge, challenge, userId, progressCallback);
+                if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+                    mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+                }
+                return response;
+            }
+        }
+        CredentialHash storedHash = mStorage.readCredentialHash(userId);
+        if (storedHash.type != credentialType) {
+            Slog.wtf(TAG, "doVerifyCredential type mismatch with stored credential??"
+                    + " stored: " + storedHash.type + " passed in: " + credentialType);
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        boolean shouldReEnrollBaseZero = storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+                && storedHash.isBaseZeroPattern;
+
+        String credentialToVerify;
+        if (shouldReEnrollBaseZero) {
+            credentialToVerify = LockPatternUtils.patternStringToBaseZero(credential);
+        } else {
+            credentialToVerify = credential;
+        }
+
+        VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
+                hasChallenge, challenge, progressCallback);
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
+            if (shouldReEnrollBaseZero) {
+                setLockCredentialInternal(credential, storedHash.type, credentialToVerify, userId);
+            }
+        }
+
+        return response;
+    }
+
+    @Override
+    public VerifyCredentialResponse verifyTiedProfileChallenge(String credential, int type,
+            long challenge, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        if (!isManagedProfileWithUnifiedLock(userId)) {
+            throw new RemoteException("User id must be managed profile with unified lock");
+        }
+        final int parentProfileId = mUserManager.getProfileParent(userId).id;
+        // Unlock parent by using parent's challenge
+        final VerifyCredentialResponse parentResponse = doVerifyCredential(
+                credential,
+                type,
+                true /* hasChallenge */,
+                challenge,
+                parentProfileId,
+                null /* progressCallback */);
+        if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            // Failed, just return parent's response
+            return parentResponse;
+        }
+
+        try {
+            // Unlock work profile, and work profile with unified lock must use password only
+            return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    true,
+                    challenge,
+                    userId, null /* progressCallback */);
+        } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                | NoSuchAlgorithmException | NoSuchPaddingException
+                | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                | BadPaddingException | CertificateException | IOException e) {
+            Slog.e(TAG, "Failed to decrypt child profile key", e);
+            throw new RemoteException("Unable to get tied profile token");
+        }
+    }
+
+    /**
+     * Lowest-level credential verification routine that talks to GateKeeper. If verification
+     * passes, unlock the corresponding user and keystore. Also handles the migration from legacy
+     * hash to GK.
+     */
+    private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
+            String credential, boolean hasChallenge, long challenge,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if ((storedHash == null || storedHash.hash.length == 0) && TextUtils.isEmpty(credential)) {
+            // don't need to pass empty credentials to GateKeeper
+            return VerifyCredentialResponse.OK;
+        }
+
+        if (storedHash == null || TextUtils.isEmpty(credential)) {
+            return VerifyCredentialResponse.ERROR;
+        }
+
+        // We're potentially going to be doing a bunch of disk I/O below as part
+        // of unlocking the user, so yell if calling from the main thread.
+        StrictMode.noteDiskRead();
+
+        if (storedHash.version == CredentialHash.VERSION_LEGACY) {
+            final byte[] hash;
+            if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
+            } else {
+                hash = mLockPatternUtils.passwordToHash(credential, userId);
+            }
+            if (Arrays.equals(hash, storedHash.hash)) {
+                if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+                    unlockKeystore(LockPatternUtils.patternStringToBaseZero(credential), userId);
+                } else {
+                    unlockKeystore(credential, userId);
+                }
+                // Users with legacy credentials don't have credential-backed
+                // FBE keys, so just pass through a fake token/secret
+                Slog.i(TAG, "Unlocking user with fake token: " + userId);
+                final byte[] fakeToken = String.valueOf(userId).getBytes();
+                unlockUser(userId, fakeToken, fakeToken);
+
+                // migrate credential to GateKeeper
+                setLockCredentialInternal(credential, storedHash.type, null, userId);
+                if (!hasChallenge) {
+                    notifyActivePasswordMetricsAvailable(credential, userId);
+                    return VerifyCredentialResponse.OK;
+                }
+                // Fall through to get the auth token. Technically this should never happen,
+                // as a user that had a legacy credential would have to unlock their device
+                // before getting to a flow with a challenge, but supporting for consistency.
+            } else {
+                return VerifyCredentialResponse.ERROR;
+            }
+        }
+        GateKeeperResponse gateKeeperResponse = getGateKeeperService()
+                .verifyChallenge(userId, challenge, storedHash.hash, credential.getBytes());
+        VerifyCredentialResponse response = convertResponse(gateKeeperResponse);
+        boolean shouldReEnroll = gateKeeperResponse.getShouldReEnroll();
+
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+
+            // credential has matched
+
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(credential, userId);
+            unlockKeystore(credential, userId);
+
+            Slog.i(TAG, "Unlocking user " + userId + " with token length "
+                    + response.getPayload().length);
+            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            if (shouldReEnroll) {
+                setLockCredentialInternal(credential, storedHash.type, credential, userId);
+            } else {
+                // Now that we've cleared of all required GK migration, let's do the final
+                // migration to synthetic password.
+                synchronized (mSpManager) {
+                    if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                        AuthenticationToken auth = initializeSyntheticPasswordLocked(
+                                storedHash.hash, credential, storedHash.type, userId);
+                        activateEscrowTokens(auth, userId);
+                    }
+                }
+            }
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) {
+        final PasswordMetrics metrics;
+        if (password == null) {
+            metrics = new PasswordMetrics();
+        } else {
+            metrics = PasswordMetrics.computeForPassword(password);
+            metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
+        }
+
+        // Asynchronous to avoid dead lock
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.setActivePasswordState(metrics, userId);
+        });
+    }
+
+    /**
+     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
+     * reporting the password changed.
+     */
+    private void notifyPasswordChanged(@UserIdInt int userId) {
+        // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering
+        mHandler.post(() -> {
+            DevicePolicyManager dpm = (DevicePolicyManager)
+                    mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+            dpm.reportPasswordChanged(userId);
+        });
+    }
+
+    @Override
+    public boolean checkVoldPassword(int userId) throws RemoteException {
+        if (!mFirstCallToVold) {
+            return false;
+        }
+        mFirstCallToVold = false;
+
+        checkPasswordReadPermission(userId);
+
+        // There's no guarantee that this will safely connect, but if it fails
+        // we will simply show the lock screen when we shouldn't, so relatively
+        // benign. There is an outside chance something nasty would happen if
+        // this service restarted before vold stales out the password in this
+        // case. The nastiness is limited to not showing the lock screen when
+        // we should, within the first minute of decrypting the phone if this
+        // service can't connect to vold, it restarts, and then the new instance
+        // does successfully connect.
+        final IStorageManager service = mInjector.getStorageManager();
+        String password;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            password = service.getPassword();
+            service.clearPassword();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        if (password == null) {
+            return false;
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPatternEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        try {
+            if (mLockPatternUtils.isLockPasswordEnabled(userId)) {
+                if (checkCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, userId,
+                        null /* progressCallback */)
+                                .getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        return false;
+    }
+
+    private void removeUser(int userId, boolean unknownUser) {
+        mSpManager.removeUser(userId);
+        mStorage.removeUser(userId);
+        mStrongAuth.removeUser(userId);
+
+        final KeyStore ks = KeyStore.getInstance();
+        ks.onUserRemoved(userId);
+
+        try {
+            final IGateKeeperService gk = getGateKeeperService();
+            if (gk != null) {
+                gk.clearSecureUserId(userId);
+            }
+        } catch (RemoteException ex) {
+            Slog.w(TAG, "unable to clear GK secure user id");
+        }
+        if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
+            removeKeystoreProfileKey(userId);
+        }
+    }
+
+    private void removeKeystoreProfileKey(int targetUserId) {
+        if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId);
+        try {
+            java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + targetUserId);
+            keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_DECRYPT + targetUserId);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            // We have tried our best to remove all keys
+            Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
+        }
+    }
+
+    @Override
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.registerStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        checkPasswordReadPermission(UserHandle.USER_ALL);
+        mStrongAuth.unregisterStrongAuthTracker(tracker);
+    }
+
+    @Override
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.requireStrongAuth(strongAuthReason, userId);
+    }
+
+    @Override
+    public void userPresent(int userId) {
+        checkWritePermission(userId);
+        mStrongAuth.reportUnlock(userId);
+    }
+
+    @Override
+    public int getStrongAuthForUser(int userId) {
+        checkPasswordReadPermission(userId);
+        return mStrongAuthTracker.getStrongAuthForUser(userId);
+    }
+
+    private boolean isCallerShell() {
+        final int callingUid = Binder.getCallingUid();
+        return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+    }
+
+    private void enforceShell() {
+        if (!isCallerShell()) {
+            throw new SecurityException("Caller must be shell");
+        }
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver)
+            throws RemoteException {
+        enforceShell();
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    private static final String[] VALID_SETTINGS = new String[] {
+            LockPatternUtils.LOCKOUT_PERMANENT_KEY,
+            LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
+            LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
+            LockPatternUtils.LOCKSCREEN_OPTIONS,
+            LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
+            LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
+            LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            Secure.LOCK_PATTERN_ENABLED,
+            Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
+            Secure.LOCK_PATTERN_VISIBLE,
+            Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
+    };
+
+    // Reading these settings needs the contacts permission
+    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO
+    };
+
+    // Reading these settings needs the same permission as checking the password
+    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
+            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
+            LockPatternUtils.PASSWORD_HISTORY_KEY,
+            LockPatternUtils.PASSWORD_TYPE_KEY,
+            SEPARATE_PROFILE_CHALLENGE_KEY
+    };
+
+    private static final String[] SETTINGS_TO_BACKUP = new String[] {
+            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
+            Secure.LOCK_SCREEN_OWNER_INFO
+    };
+
+    private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            mGateKeeperService.asBinder().unlinkToDeath(this, 0);
+            mGateKeeperService = null;
+        }
+    }
+
+    protected synchronized IGateKeeperService getGateKeeperService()
+            throws RemoteException {
+        if (mGateKeeperService != null) {
+            return mGateKeeperService;
+        }
+
+        final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE);
+        if (service != null) {
+            service.linkToDeath(new GateKeeperDiedRecipient(), 0);
+            mGateKeeperService = IGateKeeperService.Stub.asInterface(service);
+            return mGateKeeperService;
+        }
+
+        Slog.e(TAG, "Unable to acquire GateKeeperService");
+        return null;
+    }
+
+    /**
+     * Precondition: vold and keystore unlocked.
+     *
+     * Create new synthetic password, set up synthetic password blob protected by the supplied
+     * user credential, and make the newly-created SP blob active.
+     *
+     * The invariant under a synthetic password is:
+     * 1. If user credential exists, then both vold and keystore and protected with keys derived
+     *     from the synthetic password.
+     * 2. If user credential does not exist, vold and keystore protection are cleared. This is to
+     *     make it consistent with current behaviour. It also allows ActivityManager to call
+     *     unlockUser() with empty secret.
+     * 3. Once a user is migrated to have synthetic password, its value will never change, no matter
+     *     whether the user changes his lockscreen PIN or clear/reset it. When the user clears its
+     *     lockscreen PIN, we still maintain the existing synthetic password in a password blob
+     *     protected by a default PIN. The only exception is when the DPC performs an untrusted
+     *     credential change, in which case we have no way to derive the existing synthetic password
+     *     and has to create a new one.
+     * 4. The user SID is linked with synthetic password, but its cleared/re-created when the user
+     *     clears/re-creates his lockscreen PIN.
+     *
+     *
+     * Different cases of calling this method:
+     * 1. credentialHash != null
+     *     This implies credential != null, a new SP blob will be provisioned, and existing SID
+     *     migrated to associate with the new SP.
+     *     This happens during a normal migration case when the user currently has password.
+     *
+     * 2. credentialhash == null and credential == null
+     *     A new SP blob and a new SID will be created, while the user has no credentials.
+     *     This can happens when we are activating an escrow token on a unsecured device, during
+     *     which we want to create the SP structure with an empty user credential.
+     *
+     * 3. credentialhash == null and credential != null
+     *     This is the untrusted credential reset, OR the user sets a new lockscreen password
+     *     FOR THE FIRST TIME on a SP-enabled device. New credential and new SID will be created
+     */
+    private AuthenticationToken initializeSyntheticPasswordLocked(byte[] credentialHash,
+            String credential, int credentialType, int userId) throws RemoteException {
+        Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+        AuthenticationToken auth = mSpManager.newSyntheticPasswordAndSid(getGateKeeperService(),
+                credentialHash, credential, userId);
+        if (auth == null) {
+            Slog.wtf(TAG, "initializeSyntheticPasswordLocked returns null auth token");
+            return null;
+        }
+        long handle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, userId);
+        if (credential != null) {
+            if (credentialHash == null) {
+                // Since when initializing SP, we didn't provide an existing password handle
+                // for it to migrate SID, we need to create a new SID for the user.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+            }
+            mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+            setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+        } else {
+            clearUserKeyProtection(userId);
+            setKeystorePassword(null, userId);
+            getGateKeeperService().clearSecureUserId(userId);
+        }
+        fixateNewestUserKeyAuth(userId);
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, handle, userId);
+        return auth;
+    }
+
+    private long getSyntheticPasswordHandleLocked(int userId) {
+        try {
+            return getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId);
+        } catch (RemoteException e) {
+            return SyntheticPasswordManager.DEFAULT_HANDLE;
+        }
+    }
+
+    private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+      return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        // This is a global setting
+        long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+        return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
+    }
+
+    private void enableSyntheticPasswordLocked() throws RemoteException {
+        setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
+            credentialType, boolean hasChallenge, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
+        if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            userCredential = null;
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                getGateKeeperService(), handle, userCredential, userId);
+
+        VerifyCredentialResponse response = authResult.gkResponse;
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            // credential has matched
+            // perform verifyChallenge with synthetic password which generates the real auth
+            // token for the current user
+            response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+                    challenge, userId);
+            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                Slog.wtf(TAG, "verifyChallenge with SP failed.");
+                return VerifyCredentialResponse.ERROR;
+            }
+            if (progressCallback != null) {
+                progressCallback.onCredentialVerified();
+            }
+            notifyActivePasswordMetricsAvailable(userCredential, userId);
+            unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
+
+            final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
+            Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
+            unlockUser(userId, null, secret);
+
+            if (isManagedProfileWithSeparatedLock(userId)) {
+                TrustManager trustManager =
+                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+                trustManager.setDeviceLockedForUser(userId, false);
+            }
+            activateEscrowTokens(authResult.authToken, userId);
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            if (response.getTimeout() > 0) {
+                requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
+            }
+        }
+
+        return response;
+    }
+
+    /**
+     * Change the user's lockscreen password by creating a new SP blob and update the handle, based
+     * on an existing authentication token. Even though a new SP blob is created, the underlying
+     * synthetic password is never changed.
+     *
+     * When clearing credential, we keep the SP unchanged, but clear its password handle so its
+     * SID is gone. We also clear password from (software-based) keystore and vold, which will be
+     * added back when new password is set in future.
+     */
+    private long setLockCredentialWithAuthTokenLocked(String credential, int credentialType,
+            AuthenticationToken auth, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "setLockCredentialWithAuthTokenLocked: user=" + userId);
+        long newHandle = mSpManager.createPasswordBasedSyntheticPassword(getGateKeeperService(),
+                credential, credentialType, auth, userId);
+        final Map<Integer, String> profilePasswords;
+        if (credential != null) {
+            // // not needed by synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = null;
+
+            if (mSpManager.hasSidForUser(userId)) {
+                // We are changing password of a secured device, nothing more needed as
+                // createPasswordBasedSyntheticPassword has already taken care of maintaining
+                // the password handle and SID unchanged.
+
+                //refresh auth token
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+            } else {
+                // A new password is set on a previously-unsecured device, we need to generate
+                // a new SID, and re-add keys to vold and keystore.
+                mSpManager.newSidForUser(getGateKeeperService(), auth, userId);
+                mSpManager.verifyChallenge(getGateKeeperService(), auth, 0L, userId);
+                setAuthlessUserKeyProtection(userId, auth.deriveDiskEncryptionKey());
+                fixateNewestUserKeyAuth(userId);
+                setKeystorePassword(auth.deriveKeyStorePassword(), userId);
+            }
+        } else {
+            // Cache all profile password if they use unified work challenge. This will later be
+            // used to clear the profile's password in synchronizeUnifiedWorkChallengeForProfiles()
+            profilePasswords = getDecryptedPasswordsForAllTiedProfiles(userId);
+
+            // we are clearing password of a secured device, so need to nuke SID as well.
+            mSpManager.clearSidForUser(userId);
+            getGateKeeperService().clearSecureUserId(userId);
+            // Clear key from vold so ActivityManager can just unlock the user with empty secret
+            // during boot.
+            clearUserKeyProtection(userId);
+            fixateNewestUserKeyAuth(userId);
+            setKeystorePassword(null, userId);
+        }
+        setLong(SYNTHETIC_PASSWORD_HANDLE_KEY, newHandle, userId);
+        synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
+        return newHandle;
+    }
+
+    private void spBasedSetLockCredentialInternalLocked(String credential, int credentialType,
+            String savedCredential, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            // get credential from keystore when managed profile has unified lock
+            try {
+                savedCredential = getDecryptedPasswordForTiedProfile(userId);
+            } catch (FileNotFoundException e) {
+                Slog.i(TAG, "Child profile key not found");
+            } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                    | NoSuchAlgorithmException | NoSuchPaddingException
+                    | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                    | BadPaddingException | CertificateException | IOException e) {
+                Slog.e(TAG, "Failed to decrypt child profile key", e);
+            }
+        }
+        long handle = getSyntheticPasswordHandleLocked(userId);
+        AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                getGateKeeperService(), handle, savedCredential, userId);
+        VerifyCredentialResponse response = authResult.gkResponse;
+        AuthenticationToken auth = authResult.authToken;
+        if (auth != null) {
+            // We are performing a trusted credential change i.e. a correct existing credential
+            // is provided
+            setLockCredentialWithAuthTokenLocked(credential, credentialType, auth, userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else if (response != null
+                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR){
+            // We are performing an untrusted credential change i.e. by DevicePolicyManager.
+            // So provision a new SP and SID. This would invalidate existing escrow tokens.
+            // Still support this for now but this flow will be removed in the next release.
+
+            Slog.w(TAG, "Untrusted credential change invoked");
+            initializeSyntheticPasswordLocked(null, credential, credentialType, userId);
+            synchronizeUnifiedWorkChallengeForProfiles(userId, null);
+            mSpManager.destroyPasswordBasedSyntheticPassword(handle, userId);
+        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
+            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
+                    (response != null ? "rate limit exceeded" : "failed"));
+            return;
+        }
+        notifyActivePasswordMetricsAvailable(credential, userId);
+
+    }
+
+    @Override
+    public long addEscrowToken(byte[] token, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
+        synchronized (mSpManager) {
+            enableSyntheticPasswordLocked();
+            // Migrate to synthetic password based credentials if the user has no password,
+            // the token can then be activated immediately.
+            AuthenticationToken auth = null;
+            if (!isUserSecure(userId)) {
+                if (shouldMigrateToSyntheticPasswordLocked(userId)) {
+                    auth = initializeSyntheticPasswordLocked(null, null,
+                            LockPatternUtils.CREDENTIAL_TYPE_NONE, userId);
+                } else /* isSyntheticPasswordBasedCredentialLocked(userId) */ {
+                    long pwdHandle = getSyntheticPasswordHandleLocked(userId);
+                    auth = mSpManager.unwrapPasswordBasedSyntheticPassword(getGateKeeperService(),
+                            pwdHandle, null, userId).authToken;
+                }
+            }
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+                if (!mSpManager.hasEscrowData(userId)) {
+                    throw new SecurityException("Escrow token is disabled on the current user");
+                }
+            }
+            long handle = mSpManager.createTokenBasedSyntheticPassword(token, userId);
+            if (auth != null) {
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+            return handle;
+        }
+    }
+
+    private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
+        if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
+        disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
+        synchronized (mSpManager) {
+            for (long handle : mSpManager.getPendingTokensForUser(userId)) {
+                Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
+                mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            return mSpManager.existsHandle(handle, userId);
+        }
+    }
+
+    @Override
+    public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        synchronized (mSpManager) {
+            if (handle == getSyntheticPasswordHandleLocked(userId)) {
+                Slog.w(TAG, "Cannot remove password handle");
+                return false;
+            }
+            if (mSpManager.removePendingToken(handle, userId)) {
+                return true;
+            }
+            if (mSpManager.existsHandle(handle, userId)) {
+                mSpManager.destroyTokenBasedSyntheticPassword(handle, userId);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    @Override
+    public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
+            byte[] token, int userId) throws RemoteException {
+        ensureCallerSystemUid();
+        boolean result;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            result = setLockCredentialWithTokenInternal(credential, type, tokenHandle, token,
+                    userId);
+        }
+        if (result) {
+            synchronized (mSeparateChallengeLock) {
+                setSeparateProfileChallengeEnabled(userId, true, null);
+            }
+            notifyPasswordChanged(userId);
+        }
+        return result;
+    }
+
+    private boolean setLockCredentialWithTokenInternal(String credential, int type,
+            long tokenHandle, byte[] token, int userId) throws RemoteException {
+        synchronized (mSpManager) {
+            AuthenticationResult result = mSpManager.unwrapTokenBasedSyntheticPassword(
+                    getGateKeeperService(), tokenHandle, token, userId);
+            if (result.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return false;
+            }
+            long oldHandle = getSyntheticPasswordHandleLocked(userId);
+            setLockCredentialWithAuthTokenLocked(credential, type, result.authToken, userId);
+            mSpManager.destroyPasswordBasedSyntheticPassword(oldHandle, userId);
+            return true;
+        }
+    }
+
+    @Override
+    public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
+            throws RemoteException {
+        ensureCallerSystemUid();
+        AuthenticationResult authResult;
+        synchronized (mSpManager) {
+            if (!mSpManager.hasEscrowData(userId)) {
+                throw new SecurityException("Escrow token is disabled on the current user");
+            }
+            authResult = mSpManager.unwrapTokenBasedSyntheticPassword(getGateKeeperService(),
+                    tokenHandle, token, userId);
+            if (authResult.authToken == null) {
+                Slog.w(TAG, "Invalid escrow token supplied");
+                return;
+            }
+        }
+        unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
+        synchronized (this) {
+            pw.println("Current lock settings service state:");
+            pw.println(String.format("SP Enabled = %b",
+                    mLockPatternUtils.isSyntheticPasswordEnabled()));
+
+            List<UserInfo> users = mUserManager.getUsers();
+            for (int user = 0; user < users.size(); user++) {
+                final int userId = users.get(user).id;
+                pw.println("    User " + userId);
+                pw.println(String.format("        SP Handle = %x",
+                        getSyntheticPasswordHandleLocked(userId)));
+                try {
+                    pw.println(String.format("        SID = %x",
+                            getGateKeeperService().getSecureUserId(userId)));
+                } catch (RemoteException e) {
+                    // ignore.
+                }
+            }
+        }
+    }
+
+    private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            // Managed profile should have escrow enabled
+            if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+                Slog.i(TAG, "Managed profile can have escrow token");
+                return;
+            }
+            DevicePolicyManager dpm = mInjector.getDevicePolicyManager();
+            // Devices with Device Owner should have escrow enabled on all users.
+            if (dpm.getDeviceOwnerComponentOnAnyUser() != null) {
+                Slog.i(TAG, "Corp-owned device can have escrow token");
+                return;
+            }
+            // We could also have a profile owner on the given (non-managed) user for unicorn cases
+            if (dpm.getProfileOwnerAsUser(userId) != null) {
+                Slog.i(TAG, "User with profile owner can have escrow token");
+                return;
+            }
+            // If the device is yet to be provisioned (still in SUW), there is still
+            // a chance that Device Owner will be set on the device later, so postpone
+            // disabling escrow token for now.
+            if (!dpm.isDeviceProvisioned()) {
+                Slog.i(TAG, "Postpone disabling escrow tokens until device is provisioned");
+                return;
+            }
+
+            // Escrow tokens are enabled on automotive builds.
+            if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                return;
+            }
+
+            // Disable escrow token permanently on all other device/user types.
+            Slog.i(TAG, "Disabling escrow token on user " + userId);
+            if (isSyntheticPasswordBasedCredentialLocked(userId)) {
+                mSpManager.destroyEscrowData(userId);
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void ensureCallerSystemUid() throws SecurityException {
+        final int callingUid = mInjector.binderGetCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("Only system can call this API.");
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
new file mode 100644
index 0000000..d1fb28a
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+
+class LockSettingsShellCommand extends ShellCommand {
+
+    private static final String COMMAND_SET_PATTERN = "set-pattern";
+    private static final String COMMAND_SET_PIN = "set-pin";
+    private static final String COMMAND_SET_PASSWORD = "set-password";
+    private static final String COMMAND_CLEAR = "clear";
+    private static final String COMMAND_SP = "sp";
+    private static final String COMMAND_SET_DISABLED = "set-disabled";
+
+    private int mCurrentUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final Context mContext;
+    private String mOld = "";
+    private String mNew = "";
+
+    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        try {
+            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
+
+            parseArgs();
+            if (!checkCredential()) {
+                return -1;
+            }
+            switch (cmd) {
+                case COMMAND_SET_PATTERN:
+                    runSetPattern();
+                    break;
+                case COMMAND_SET_PASSWORD:
+                    runSetPassword();
+                    break;
+                case COMMAND_SET_PIN:
+                    runSetPin();
+                    break;
+                case COMMAND_CLEAR:
+                    runClear();
+                    break;
+                case COMMAND_SP:
+                    runEnableSp();
+                    break;
+                case COMMAND_SET_DISABLED:
+                    runSetDisabled();
+                    break;
+                default:
+                    getErrPrintWriter().println("Unknown command: " + cmd);
+                    break;
+            }
+            return 0;
+        } catch (Exception e) {
+            getErrPrintWriter().println("Error while executing command: " + cmd);
+            e.printStackTrace(getErrPrintWriter());
+            return -1;
+        }
+    }
+
+    @Override
+    public void onHelp() {
+    }
+
+    private void parseArgs() {
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("--old".equals(opt)) {
+                mOld = getNextArgRequired();
+            } else if ("--user".equals(opt)) {
+                mCurrentUserId = Integer.parseInt(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Unknown option: " + opt);
+                throw new IllegalArgumentException();
+            }
+        }
+        mNew = getNextArg();
+    }
+
+    private void runEnableSp() {
+        if (mNew != null) {
+            mLockPatternUtils.enableSyntheticPassword();
+            getOutPrintWriter().println("Synthetic password enabled");
+        }
+        getOutPrintWriter().println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+    }
+
+    private void runSetPattern() throws RemoteException {
+        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
+        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
+    }
+
+    private void runSetPassword() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
+        getOutPrintWriter().println("Password set to '" + mNew + "'");
+    }
+
+    private void runSetPin() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
+        getOutPrintWriter().println("Pin set to '" + mNew + "'");
+    }
+
+    private void runClear() throws RemoteException {
+        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
+        getOutPrintWriter().println("Lock credential cleared");
+    }
+
+    private void runSetDisabled() throws RemoteException {
+        final boolean disabled = Boolean.parseBoolean(mNew);
+        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
+        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
+    }
+
+    private boolean checkCredential() throws RemoteException, RequestThrottledException {
+        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
+        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
+        if (havePassword || havePattern) {
+            boolean result;
+            if (havePassword) {
+                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
+            } else {
+                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
+                        mCurrentUserId);
+            }
+            if (result) {
+                return true;
+            } else {
+                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
new file mode 100644
index 0000000..861209d
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.content.Context.USER_SERVICE;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Environment;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Storage for the lock settings service.
+ */
+class LockSettingsStorage {
+
+    private static final String TAG = "LockSettingsStorage";
+    private static final String TABLE = "locksettings";
+    private static final boolean DEBUG = false;
+
+    private static final String COLUMN_KEY = "name";
+    private static final String COLUMN_USERID = "user";
+    private static final String COLUMN_VALUE = "value";
+
+    private static final String[] COLUMNS_FOR_QUERY = {
+            COLUMN_VALUE
+    };
+    private static final String[] COLUMNS_FOR_PREFETCH = {
+            COLUMN_KEY, COLUMN_VALUE
+    };
+
+    private static final String SYSTEM_DIRECTORY = "/system/";
+    private static final String LOCK_PATTERN_FILE = "gatekeeper.pattern.key";
+    private static final String BASE_ZERO_LOCK_PATTERN_FILE = "gatekeeper.gesture.key";
+    private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key";
+    private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key";
+    private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key";
+    private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key";
+
+    private static final String SYNTHETIC_PASSWORD_DIRECTORY = "spblob/";
+
+    private static final Object DEFAULT = new Object();
+
+    private final DatabaseHelper mOpenHelper;
+    private final Context mContext;
+    private final Cache mCache = new Cache();
+    private final Object mFileWriteLock = new Object();
+
+    @VisibleForTesting
+    public static class CredentialHash {
+        static final int VERSION_LEGACY = 0;
+        static final int VERSION_GATEKEEPER = 1;
+
+        private CredentialHash(byte[] hash, int type, int version) {
+            if (type != LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                if (hash == null) {
+                    throw new RuntimeException("Empty hash for CredentialHash");
+                }
+            } else /* type == LockPatternUtils.CREDENTIAL_TYPE_NONE */ {
+                if (hash != null) {
+                    throw new RuntimeException("None type CredentialHash should not have hash");
+                }
+            }
+            this.hash = hash;
+            this.type = type;
+            this.version = version;
+            this.isBaseZeroPattern = false;
+        }
+
+        private CredentialHash(byte[] hash, boolean isBaseZeroPattern) {
+            this.hash = hash;
+            this.type = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+            this.version = VERSION_GATEKEEPER;
+            this.isBaseZeroPattern = isBaseZeroPattern;
+        }
+
+        static CredentialHash create(byte[] hash, int type) {
+            if (type == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+                throw new RuntimeException("Bad type for CredentialHash");
+            }
+            return new CredentialHash(hash, type, VERSION_GATEKEEPER);
+        }
+
+        static CredentialHash createEmptyHash() {
+            return new CredentialHash(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
+                    VERSION_GATEKEEPER);
+        }
+
+        byte[] hash;
+        int type;
+        int version;
+        boolean isBaseZeroPattern;
+    }
+
+    public LockSettingsStorage(Context context) {
+        mContext = context;
+        mOpenHelper = new DatabaseHelper(context);
+    }
+
+    public void setDatabaseOnCreateCallback(Callback callback) {
+        mOpenHelper.setCallback(callback);
+    }
+
+    public void writeKeyValue(String key, String value, int userId) {
+        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
+    }
+
+    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
+        ContentValues cv = new ContentValues();
+        cv.put(COLUMN_KEY, key);
+        cv.put(COLUMN_USERID, userId);
+        cv.put(COLUMN_VALUE, value);
+
+        db.beginTransaction();
+        try {
+            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
+                    new String[] {key, Integer.toString(userId)});
+            db.insert(TABLE, null, cv);
+            db.setTransactionSuccessful();
+            mCache.putKeyValue(key, value, userId);
+        } finally {
+            db.endTransaction();
+        }
+
+    }
+
+    public String readKeyValue(String key, String defaultValue, int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasKeyValue(key, userId)) {
+                return mCache.peekKeyValue(key, defaultValue, userId);
+            }
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        Object result = DEFAULT;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY,
+                COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?",
+                new String[] { Integer.toString(userId), key },
+                null, null, null)) != null) {
+            if (cursor.moveToFirst()) {
+                result = cursor.getString(0);
+            }
+            cursor.close();
+        }
+        mCache.putKeyValueIfUnchanged(key, result, userId, version);
+        return result == DEFAULT ? defaultValue : (String) result;
+    }
+
+    public void prefetchUser(int userId) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.isFetched(userId)) {
+                return;
+            }
+            mCache.setFetched(userId);
+            version = mCache.getVersion();
+        }
+
+        Cursor cursor;
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
+                COLUMN_USERID + "=?",
+                new String[] { Integer.toString(userId) },
+                null, null, null)) != null) {
+            while (cursor.moveToNext()) {
+                String key = cursor.getString(0);
+                String value = cursor.getString(1);
+                mCache.putKeyValueIfUnchanged(key, value, userId, version);
+            }
+            cursor.close();
+        }
+
+        // Populate cache by reading the password and pattern files.
+        readCredentialHash(userId);
+    }
+
+    private CredentialHash readPasswordHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getLegacyLockPasswordFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    private CredentialHash readPatternHashIfExists(int userId) {
+        byte[] stored = readFile(getLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_GATEKEEPER);
+        }
+
+        stored = readFile(getBaseZeroLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, true);
+        }
+
+        stored = readFile(getLegacyLockPatternFilename(userId));
+        if (!ArrayUtils.isEmpty(stored)) {
+            return new CredentialHash(stored, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                    CredentialHash.VERSION_LEGACY);
+        }
+        return null;
+    }
+
+    public CredentialHash readCredentialHash(int userId) {
+        CredentialHash passwordHash = readPasswordHashIfExists(userId);
+        CredentialHash patternHash = readPatternHashIfExists(userId);
+        if (passwordHash != null && patternHash != null) {
+            if (passwordHash.version == CredentialHash.VERSION_GATEKEEPER) {
+                return passwordHash;
+            } else {
+                return patternHash;
+            }
+        } else if (passwordHash != null) {
+            return passwordHash;
+        } else if (patternHash != null) {
+            return patternHash;
+        } else {
+            return CredentialHash.createEmptyHash();
+        }
+    }
+
+    public void removeChildProfileLock(int userId) {
+        if (DEBUG)
+            Slog.e(TAG, "Remove child profile lock for user: " + userId);
+        try {
+            deleteFile(getChildProfileLockFile(userId));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void writeChildProfileLock(int userId, byte[] lock) {
+        writeFile(getChildProfileLockFile(userId), lock);
+    }
+
+    public byte[] readChildProfileLock(int userId) {
+        return readFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasChildProfileLock(int userId) {
+        return hasFile(getChildProfileLockFile(userId));
+    }
+
+    public boolean hasPassword(int userId) {
+        return hasFile(getLockPasswordFilename(userId)) ||
+            hasFile(getLegacyLockPasswordFilename(userId));
+    }
+
+    public boolean hasPattern(int userId) {
+        return hasFile(getLockPatternFilename(userId)) ||
+            hasFile(getBaseZeroLockPatternFilename(userId)) ||
+            hasFile(getLegacyLockPatternFilename(userId));
+    }
+
+    public boolean hasCredential(int userId) {
+        return hasPassword(userId) || hasPattern(userId);
+    }
+
+    private boolean hasFile(String name) {
+        byte[] contents = readFile(name);
+        return contents != null && contents.length > 0;
+    }
+
+    private byte[] readFile(String name) {
+        int version;
+        synchronized (mCache) {
+            if (mCache.hasFile(name)) {
+                return mCache.peekFile(name);
+            }
+            version = mCache.getVersion();
+        }
+
+        RandomAccessFile raf = null;
+        byte[] stored = null;
+        try {
+            raf = new RandomAccessFile(name, "r");
+            stored = new byte[(int) raf.length()];
+            raf.readFully(stored, 0, stored.length);
+            raf.close();
+        } catch (IOException e) {
+            Slog.e(TAG, "Cannot read file " + e);
+        } finally {
+            if (raf != null) {
+                try {
+                    raf.close();
+                } catch (IOException e) {
+                    Slog.e(TAG, "Error closing file " + e);
+                }
+            }
+        }
+        mCache.putFileIfUnchanged(name, stored, version);
+        return stored;
+    }
+
+    private void writeFile(String name, byte[] hash) {
+        synchronized (mFileWriteLock) {
+            RandomAccessFile raf = null;
+            try {
+                // Write the hash to file
+                raf = new RandomAccessFile(name, "rw");
+                // Truncate the file if pattern is null, to clear the lock
+                if (hash == null || hash.length == 0) {
+                    raf.setLength(0);
+                } else {
+                    raf.write(hash, 0, hash.length);
+                }
+                raf.close();
+            } catch (IOException e) {
+                Slog.e(TAG, "Error writing to file " + e);
+            } finally {
+                if (raf != null) {
+                    try {
+                        raf.close();
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error closing file " + e);
+                    }
+                }
+            }
+            mCache.putFile(name, hash);
+        }
+    }
+
+    private void deleteFile(String name) {
+        if (DEBUG) Slog.e(TAG, "Delete file " + name);
+        synchronized (mFileWriteLock) {
+            File file = new File(name);
+            if (file.exists()) {
+                file.delete();
+                mCache.putFile(name, null);
+            }
+        }
+    }
+
+    public void writeCredentialHash(CredentialHash hash, int userId) {
+        byte[] patternHash = null;
+        byte[] passwordHash = null;
+
+        if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            passwordHash = hash.hash;
+        } else if (hash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
+            patternHash = hash.hash;
+        }
+        writeFile(getLockPasswordFilename(userId), passwordHash);
+        writeFile(getLockPatternFilename(userId), patternHash);
+    }
+
+    @VisibleForTesting
+    String getLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getLegacyLockPasswordFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, LEGACY_LOCK_PASSWORD_FILE);
+    }
+
+    private String getBaseZeroLockPatternFilename(int userId) {
+        return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE);
+    }
+
+    @VisibleForTesting
+    String getChildProfileLockFile(int userId) {
+        return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE);
+    }
+
+    private String getLockCredentialFilePathForUser(int userId, String basename) {
+        String dataSystemDirectory = Environment.getDataDirectory().getAbsolutePath() +
+                        SYSTEM_DIRECTORY;
+        if (userId == 0) {
+            // Leave it in the same place for user 0
+            return dataSystemDirectory + basename;
+        } else {
+            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
+        }
+    }
+
+    public void writeSyntheticPasswordState(int userId, long handle, String name, byte[] data) {
+        writeFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name), data);
+    }
+
+    public byte[] readSyntheticPasswordState(int userId, long handle, String name) {
+        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
+    }
+
+    public void deleteSyntheticPasswordState(int userId, long handle, String name, boolean secure) {
+        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
+        File file = new File(path);
+        if (file.exists()) {
+            //TODO: (b/34600579) invoke secdiscardable
+            file.delete();
+            mCache.putFile(path, null);
+        }
+    }
+
+    public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
+        Map<Integer, List<Long>> result = new ArrayMap<>();
+        final UserManager um = UserManager.get(mContext);
+        for (UserInfo user : um.getUsers(false)) {
+            result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
+        }
+        return result;
+    }
+
+    public List<Long> listSyntheticPasswordHandlesForUser(String stateName, int userId) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        List<Long> result = new ArrayList<>();
+        File[] files = baseDir.listFiles();
+        if (files == null) {
+            return result;
+        }
+        for (File file : files) {
+            String[] parts = file.getName().split("\\.");
+            if (parts.length == 2 && parts[1].equals(stateName)) {
+                try {
+                    result.add(Long.parseUnsignedLong(parts[0], 16));
+                } catch (NumberFormatException e) {
+                    Slog.e(TAG, "Failed to parse handle " + parts[0]);
+                }
+            }
+        }
+        return result;
+    }
+
+    @VisibleForTesting
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return new File(Environment.getDataSystemDeDirectory(userId) ,SYNTHETIC_PASSWORD_DIRECTORY);
+    }
+
+    @VisibleForTesting
+    protected String getSynthenticPasswordStateFilePathForUser(int userId, long handle,
+            String name) {
+        File baseDir = getSyntheticPasswordDirectoryForUser(userId);
+        String baseName = String.format("%016x.%s", handle, name);
+        if (!baseDir.exists()) {
+            baseDir.mkdir();
+        }
+        return new File(baseDir, baseName).getAbsolutePath();
+    }
+
+    public void removeUser(int userId) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+        final UserInfo parentInfo = um.getProfileParent(userId);
+
+        if (parentInfo == null) {
+            // This user owns its lock settings files - safe to delete them
+            synchronized (mFileWriteLock) {
+                String name = getLockPasswordFilename(userId);
+                File file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+                name = getLockPatternFilename(userId);
+                file = new File(name);
+                if (file.exists()) {
+                    file.delete();
+                    mCache.putFile(name, null);
+                }
+            }
+        } else {
+            // Managed profile
+            removeChildProfileLock(userId);
+        }
+
+        File spStateDir = getSyntheticPasswordDirectoryForUser(userId);
+        try {
+            db.beginTransaction();
+            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
+            db.setTransactionSuccessful();
+            mCache.removeUser(userId);
+            // The directory itself will be deleted as part of user deletion operation by the
+            // framework, so only need to purge cache here.
+            //TODO: (b/34600579) invoke secdiscardable
+            mCache.purgePath(spStateDir.getAbsolutePath());
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    @VisibleForTesting
+    void closeDatabase() {
+        mOpenHelper.close();
+    }
+
+    @VisibleForTesting
+    void clearCache() {
+        mCache.clear();
+    }
+
+    public interface Callback {
+        void initialize(SQLiteDatabase db);
+    }
+
+    class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String TAG = "LockSettingsDB";
+        private static final String DATABASE_NAME = "locksettings.db";
+
+        private static final int DATABASE_VERSION = 2;
+
+        private Callback mCallback;
+
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            setWriteAheadLoggingEnabled(true);
+        }
+
+        public void setCallback(Callback callback) {
+            mCallback = callback;
+        }
+
+        private void createTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE + " (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    COLUMN_KEY + " TEXT," +
+                    COLUMN_USERID + " INTEGER," +
+                    COLUMN_VALUE + " TEXT" +
+                    ");");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            createTable(db);
+            if (mCallback != null) {
+                mCallback.initialize(db);
+            }
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
+            int upgradeVersion = oldVersion;
+            if (upgradeVersion == 1) {
+                // Previously migrated lock screen widget settings. Now defunct.
+                upgradeVersion = 2;
+            }
+
+            if (upgradeVersion != DATABASE_VERSION) {
+                Log.w(TAG, "Failed to upgrade database!");
+            }
+        }
+    }
+
+    /**
+     * Cache consistency model:
+     * - Writes to storage write directly to the cache, but this MUST happen within the atomic
+     *   section either provided by the database transaction or mWriteLock, such that writes to the
+     *   cache and writes to the backing storage are guaranteed to occur in the same order
+     *
+     * - Reads can populate the cache, but because they are no strong ordering guarantees with
+     *   respect to writes this precaution is taken:
+     *   - The cache is assigned a version number that increases every time the cache is modified.
+     *     Reads from backing storage can only populate the cache if the backing storage
+     *     has not changed since the load operation has begun.
+     *     This guarantees that no read operation can shadow a write to the cache that happens
+     *     after it had begun.
+     */
+    private static class Cache {
+        private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>();
+        private final CacheKey mCacheKey = new CacheKey();
+        private int mVersion = 0;
+
+        String peekKeyValue(String key, String defaultValue, int userId) {
+            Object cached = peek(CacheKey.TYPE_KEY_VALUE, key, userId);
+            return cached == DEFAULT ? defaultValue : (String) cached;
+        }
+
+        boolean hasKeyValue(String key, int userId) {
+            return contains(CacheKey.TYPE_KEY_VALUE, key, userId);
+        }
+
+        void putKeyValue(String key, String value, int userId) {
+            put(CacheKey.TYPE_KEY_VALUE, key, value, userId);
+        }
+
+        void putKeyValueIfUnchanged(String key, Object value, int userId, int version) {
+            putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
+        }
+
+        byte[] peekFile(String fileName) {
+            return (byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        boolean hasFile(String fileName) {
+            return contains(CacheKey.TYPE_FILE, fileName, -1 /* userId */);
+        }
+
+        void putFile(String key, byte[] value) {
+            put(CacheKey.TYPE_FILE, key, value, -1 /* userId */);
+        }
+
+        void putFileIfUnchanged(String key, byte[] value, int version) {
+            putIfUnchanged(CacheKey.TYPE_FILE, key, value, -1 /* userId */, version);
+        }
+
+        void setFetched(int userId) {
+            put(CacheKey.TYPE_FETCHED, "isFetched", "true", userId);
+        }
+
+        boolean isFetched(int userId) {
+            return contains(CacheKey.TYPE_FETCHED, "", userId);
+        }
+
+
+        private synchronized void put(int type, String key, Object value, int userId) {
+            // Create a new CachKey here because it may be saved in the map if the key is absent.
+            mCache.put(new CacheKey().set(type, key, userId), value);
+            mVersion++;
+        }
+
+        private synchronized void putIfUnchanged(int type, String key, Object value, int userId,
+                int version) {
+            if (!contains(type, key, userId) && mVersion == version) {
+                put(type, key, value, userId);
+            }
+        }
+
+        private synchronized boolean contains(int type, String key, int userId) {
+            return mCache.containsKey(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized Object peek(int type, String key, int userId) {
+            return mCache.get(mCacheKey.set(type, key, userId));
+        }
+
+        private synchronized int getVersion() {
+            return mVersion;
+        }
+
+        synchronized void removeUser(int userId) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                if (mCache.keyAt(i).userId == userId) {
+                    mCache.removeAt(i);
+                }
+            }
+
+            // Make sure in-flight loads can't write to cache.
+            mVersion++;
+        }
+
+        synchronized void purgePath(String path) {
+            for (int i = mCache.size() - 1; i >= 0; i--) {
+                CacheKey entry = mCache.keyAt(i);
+                if (entry.type == CacheKey.TYPE_FILE && entry.key.startsWith(path)) {
+                    mCache.removeAt(i);
+                }
+            }
+            mVersion++;
+        }
+
+        synchronized void clear() {
+            mCache.clear();
+            mVersion++;
+        }
+
+        private static final class CacheKey {
+            static final int TYPE_KEY_VALUE = 0;
+            static final int TYPE_FILE = 1;
+            static final int TYPE_FETCHED = 2;
+
+            String key;
+            int userId;
+            int type;
+
+            public CacheKey set(int type, String key, int userId) {
+                this.type = type;
+                this.key = key;
+                this.userId = userId;
+                return this;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (!(obj instanceof CacheKey))
+                    return false;
+                CacheKey o = (CacheKey) obj;
+                return userId == o.userId && type == o.type && key.equals(o.key);
+            }
+
+            @Override
+            public int hashCode() {
+                return key.hashCode() ^ userId ^ type;
+            }
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
new file mode 100644
index 0000000..0966153
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
+
+import android.app.AlarmManager;
+import android.app.AlarmManager.OnAlarmListener;
+import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
+import android.content.Context;
+import android.os.Binder;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.util.SparseIntArray;
+
+import java.util.ArrayList;
+
+/**
+ * Keeps track of requests for strong authentication.
+ */
+public class LockSettingsStrongAuth {
+
+    private static final String TAG = "LockSettings";
+
+    private static final int MSG_REQUIRE_STRONG_AUTH = 1;
+    private static final int MSG_REGISTER_TRACKER = 2;
+    private static final int MSG_UNREGISTER_TRACKER = 3;
+    private static final int MSG_REMOVE_USER = 4;
+    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
+
+    private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
+            "LockSettingsStrongAuth.timeoutForUser";
+
+    private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
+    private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
+    private final ArrayMap<Integer, StrongAuthTimeoutAlarmListener>
+            mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>();
+    private final int mDefaultStrongAuthFlags;
+    private final Context mContext;
+
+    private AlarmManager mAlarmManager;
+
+    public LockSettingsStrongAuth(Context context) {
+        mContext = context;
+        mDefaultStrongAuthFlags = StrongAuthTracker.getDefaultFlags(context);
+        mAlarmManager = context.getSystemService(AlarmManager.class);
+    }
+
+    private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                return;
+            }
+        }
+        mStrongAuthTrackers.add(tracker);
+
+        for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+            int key = mStrongAuthForUser.keyAt(i);
+            int value = mStrongAuthForUser.valueAt(i);
+            try {
+                tracker.onStrongAuthRequiredChanged(value, key);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
+                mStrongAuthTrackers.remove(i);
+                return;
+            }
+        }
+    }
+
+    private void handleRequireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            for (int i = 0; i < mStrongAuthForUser.size(); i++) {
+                int key = mStrongAuthForUser.keyAt(i);
+                handleRequireStrongAuthOneUser(strongAuthReason, key);
+            }
+        } else {
+            handleRequireStrongAuthOneUser(strongAuthReason, userId);
+        }
+    }
+
+    private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
+        int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags);
+        int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
+                ? STRONG_AUTH_NOT_REQUIRED
+                : (oldValue | strongAuthReason);
+        if (oldValue != newValue) {
+            mStrongAuthForUser.put(userId, newValue);
+            notifyStrongAuthTrackers(newValue, userId);
+        }
+    }
+
+    private void handleRemoveUser(int userId) {
+        int index = mStrongAuthForUser.indexOfKey(userId);
+        if (index >= 0) {
+            mStrongAuthForUser.removeAt(index);
+            notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId);
+        }
+    }
+
+    private void handleScheduleStrongAuthTimeout(int userId) {
+        final DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
+        // cancel current alarm listener for the user (if there was one)
+        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+        if (alarm != null) {
+            mAlarmManager.cancel(alarm);
+        } else {
+            alarm = new StrongAuthTimeoutAlarmListener(userId);
+            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
+        }
+        // schedule a new alarm listener for the user
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
+                alarm, mHandler);
+    }
+
+    private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
+        for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
+            try {
+                mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
+            } catch (DeadObjectException e) {
+                Slog.d(TAG, "Removing dead StrongAuthTracker.");
+                mStrongAuthTrackers.remove(i);
+                i--;
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
+            }
+        }
+    }
+
+    public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
+        mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
+    }
+
+    public void removeUser(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
+    }
+
+    public void requireStrongAuth(int strongAuthReason, int userId) {
+        if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
+            mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
+                    userId).sendToTarget();
+        } else {
+            throw new IllegalArgumentException(
+                    "userId must be an explicit user id or USER_ALL");
+        }
+    }
+
+    public void reportUnlock(int userId) {
+        requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
+    }
+
+    public void reportSuccessfulStrongAuthUnlock(int userId) {
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
+    }
+
+    private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
+
+        private final int mUserId;
+
+        public StrongAuthTimeoutAlarmListener(int userId) {
+            mUserId = userId;
+        }
+
+        @Override
+        public void onAlarm() {
+            requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId);
+        }
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REGISTER_TRACKER:
+                    handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_UNREGISTER_TRACKER:
+                    handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
+                    break;
+                case MSG_REQUIRE_STRONG_AUTH:
+                    handleRequireStrongAuth(msg.arg1, msg.arg2);
+                    break;
+                case MSG_REMOVE_USER:
+                    handleRemoveUser(msg.arg1);
+                    break;
+                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
+                    handleScheduleStrongAuthTimeout(msg.arg1);
+                    break;
+            }
+        }
+    };
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
new file mode 100644
index 0000000..b7bca1fb
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.locksettings;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class SyntheticPasswordCrypto {
+    private static final int PROFILE_KEY_IV_SIZE = 12;
+    private static final int AES_KEY_LENGTH = 32; // 256-bit AES key
+    private static final byte[] APPLICATION_ID_PERSONALIZATION = "application-id".getBytes();
+    // Time between the user credential is verified with GK and the decryption of synthetic password
+    // under the auth-bound key. This should always happen one after the other, but give it 15
+    // seconds just to be sure.
+    private static final int USER_AUTHENTICATION_VALIDITY = 15;
+
+    private static byte[] decrypt(SecretKey key, byte[] blob)
+            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        byte[] iv = Arrays.copyOfRange(blob, 0, PROFILE_KEY_IV_SIZE);
+        byte[] ciphertext = Arrays.copyOfRange(blob, PROFILE_KEY_IV_SIZE, blob.length);
+        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
+        return cipher.doFinal(ciphertext);
+    }
+
+    private static byte[] encrypt(SecretKey key, byte[] blob)
+            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
+            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
+        if (blob == null) {
+            return null;
+        }
+        Cipher cipher = Cipher.getInstance(
+                KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+                        + KeyProperties.ENCRYPTION_PADDING_NONE);
+        cipher.init(Cipher.ENCRYPT_MODE, key);
+        byte[] ciphertext = cipher.doFinal(blob);
+        byte[] iv = cipher.getIV();
+        if (iv.length != PROFILE_KEY_IV_SIZE) {
+            throw new RuntimeException("Invalid iv length: " + iv.length);
+        }
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        outputStream.write(iv);
+        outputStream.write(ciphertext);
+        return outputStream.toByteArray();
+    }
+
+    public static byte[] encrypt(byte[] keyBytes, byte[] personalisation, byte[] message) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return encrypt(key, message);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException | IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decrypt(byte[] keyBytes, byte[] personalisation, byte[] ciphertext) {
+        byte[] keyHash = personalisedHash(personalisation, keyBytes);
+        SecretKeySpec key = new SecretKeySpec(Arrays.copyOf(keyHash, AES_KEY_LENGTH),
+                KeyProperties.KEY_ALGORITHM_AES);
+        try {
+            return decrypt(key, ciphertext);
+        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
+                | IllegalBlockSizeException | BadPaddingException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+
+            SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
+            byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
+            return decrypt(decryptionKey, intermediate);
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException | UnrecoverableKeyException
+                | InvalidAlgorithmParameterException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to decrypt blob", e);
+        }
+    }
+
+    public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
+        try {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
+            keyGenerator.init(new SecureRandom());
+            SecretKey secretKey = keyGenerator.generateKey();
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .setCriticalToDeviceEncryption(true);
+            if (sid != 0) {
+                builder.setUserAuthenticationRequired(true)
+                        .setBoundToSpecificSecureUserId(sid)
+                        .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
+            }
+
+            keyStore.setEntry(keyAlias,
+                    new KeyStore.SecretKeyEntry(secretKey),
+                    builder.build());
+            byte[] intermediate = encrypt(secretKey, data);
+            return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
+
+        } catch (CertificateException | IOException | BadPaddingException
+                | IllegalBlockSizeException
+                | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
+                | InvalidKeyException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Failed to encrypt blob", e);
+        }
+    }
+
+    public static void destroyBlobKey(String keyAlias) {
+        KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            keyStore.deleteEntry(keyAlias);
+        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException
+                | IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected static byte[] personalisedHash(byte[] personalisation, byte[]... message) {
+        try {
+            final int PADDING_LENGTH = 128;
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            if (personalisation.length > PADDING_LENGTH) {
+                throw new RuntimeException("Personalisation too long");
+            }
+            // Personalize the hash
+            // Pad it to the block size of the hash function
+            personalisation = Arrays.copyOf(personalisation, PADDING_LENGTH);
+            digest.update(personalisation);
+            for (byte[] data : message) {
+                digest.update(data);
+            }
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
new file mode 100644
index 0000000..e2ec92b
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.locksettings;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverReadStatus;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.os.RemoteException;
+import android.security.GateKeeper;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+
+import libcore.util.HexEncoding;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+
+/**
+ * A class that maintains the wrapping of synthetic password by user credentials or escrow tokens.
+ * It's (mostly) a pure storage for synthetic passwords, providing APIs to creating and destroying
+ * synthetic password blobs which are wrapped by user credentials or escrow tokens.
+ *
+ * Here is the assumptions it makes:
+ *   Each user has one single synthetic password at any time.
+ *   The SP has an associated password handle, which binds to the SID for that user. The password
+ *   handle is persisted by SyntheticPasswordManager internally.
+ *   If the user credential is null, it's treated as if the credential is DEFAULT_PASSWORD
+ *
+ * Information persisted on disk:
+ *   for each user (stored under DEFAULT_HANDLE):
+ *     SP_HANDLE_NAME: GateKeeper password handle of synthetic password. Only available if user
+ *                     credential exists, cleared when user clears their credential.
+ *     SP_E0_NAME, SP_P1_NAME: Secret to derive synthetic password when combined with escrow
+ *                     tokens. Destroyed when escrow support is turned off for the given user.
+ *
+ *     for each SP blob under the user (stored under the corresponding handle):
+ *       SP_BLOB_NAME: The encrypted synthetic password. Always exists.
+ *       PASSWORD_DATA_NAME: Metadata about user credential. Only exists for password based SP.
+ *       SECDISCARDABLE_NAME: Part of the necessary ingredient to decrypt SP_BLOB_NAME for the
+ *                            purpose of secure deletion. Exists if this is a non-weaver SP
+ *                            (both password and token based), or it's a token-based SP under weaver.
+ *       WEAVER_SLOT: Metadata about the weaver slot used. Only exists if this is a SP under weaver.
+ *
+ *
+ */
+public class SyntheticPasswordManager {
+    private static final String SP_BLOB_NAME = "spblob";
+    private static final String SP_E0_NAME = "e0";
+    private static final String SP_P1_NAME = "p1";
+    private static final String SP_HANDLE_NAME = "handle";
+    private static final String SECDISCARDABLE_NAME = "secdis";
+    private static final int SECDISCARDABLE_LENGTH = 16 * 1024;
+    private static final String PASSWORD_DATA_NAME = "pwd";
+    private static final String WEAVER_SLOT_NAME = "weaver";
+
+    public static final long DEFAULT_HANDLE = 0L;
+    private static final String DEFAULT_PASSWORD = "default-password";
+
+    private static final byte WEAVER_VERSION = 1;
+    private static final int INVALID_WEAVER_SLOT = -1;
+
+    private static final byte SYNTHETIC_PASSWORD_VERSION = 1;
+    private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
+    private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
+
+    // 256-bit synthetic password
+    private static final byte SYNTHETIC_PASSWORD_LENGTH = 256 / 8;
+
+    private static final int PASSWORD_SCRYPT_N = 11;
+    private static final int PASSWORD_SCRYPT_R = 3;
+    private static final int PASSWORD_SCRYPT_P = 1;
+    private static final int PASSWORD_SALT_LENGTH = 16;
+    private static final int PASSWORD_TOKEN_LENGTH = 32;
+    private static final String TAG = "SyntheticPasswordManager";
+
+    private static final byte[] PERSONALISATION_SECDISCARDABLE = "secdiscardable-transform".getBytes();
+    private static final byte[] PERSONALIZATION_KEY_STORE_PASSWORD = "keystore-password".getBytes();
+    private static final byte[] PERSONALIZATION_USER_GK_AUTH = "user-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
+    private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
+    private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
+    private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes();
+    private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes();
+
+    static class AuthenticationResult {
+        public AuthenticationToken authToken;
+        public VerifyCredentialResponse gkResponse;
+    }
+
+    static class AuthenticationToken {
+        /*
+         * Here is the relationship between all three fields:
+         * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not.
+         * syntheticPassword = hash(P0 || P1)
+         * E0 = P0 encrypted under syntheticPassword, stored on disk.
+         */
+        private @Nullable byte[] E0;
+        private @Nullable byte[] P1;
+        private @NonNull String syntheticPassword;
+
+        public String deriveKeyStorePassword() {
+            return bytesToHex(SyntheticPasswordCrypto.personalisedHash(
+                    PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes()));
+        }
+
+        public byte[] deriveGkPassword() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH,
+                    syntheticPassword.getBytes());
+        }
+
+        public byte[] deriveDiskEncryptionKey() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY,
+                    syntheticPassword.getBytes());
+        }
+
+        private void initialize(byte[] P0, byte[] P1) {
+            this.P1 = P1;
+            this.syntheticPassword = String.valueOf(HexEncoding.encode(
+                    SyntheticPasswordCrypto.personalisedHash(
+                            PERSONALIZATION_SP_SPLIT, P0, P1)));
+            this.E0 = SyntheticPasswordCrypto.encrypt(this.syntheticPassword.getBytes(),
+                    PERSONALIZATION_E0, P0);
+        }
+
+        public void recreate(byte[] secret) {
+            initialize(secret, this.P1);
+        }
+
+        protected static AuthenticationToken create() {
+            AuthenticationToken result = new AuthenticationToken();
+            result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH),
+                    secureRandom(SYNTHETIC_PASSWORD_LENGTH));
+            return result;
+        }
+
+        public byte[] computeP0() {
+            if (E0 == null) {
+                return null;
+            }
+            return SyntheticPasswordCrypto.decrypt(syntheticPassword.getBytes(), PERSONALIZATION_E0,
+                    E0);
+        }
+    }
+
+    static class PasswordData {
+        byte scryptN;
+        byte scryptR;
+        byte scryptP;
+        public int passwordType;
+        byte[] salt;
+        // For GateKeeper-based credential, this is the password handle returned by GK,
+        // for weaver-based credential, this is empty.
+        public byte[] passwordHandle;
+
+        public static PasswordData create(int passwordType) {
+            PasswordData result = new PasswordData();
+            result.scryptN = PASSWORD_SCRYPT_N;
+            result.scryptR = PASSWORD_SCRYPT_R;
+            result.scryptP = PASSWORD_SCRYPT_P;
+            result.passwordType = passwordType;
+            result.salt = secureRandom(PASSWORD_SALT_LENGTH);
+            return result;
+        }
+
+        public static PasswordData fromBytes(byte[] data) {
+            PasswordData result = new PasswordData();
+            ByteBuffer buffer = ByteBuffer.allocate(data.length);
+            buffer.put(data, 0, data.length);
+            buffer.flip();
+            result.passwordType = buffer.getInt();
+            result.scryptN = buffer.get();
+            result.scryptR = buffer.get();
+            result.scryptP = buffer.get();
+            int saltLen = buffer.getInt();
+            result.salt = new byte[saltLen];
+            buffer.get(result.salt);
+            int handleLen = buffer.getInt();
+            if (handleLen > 0) {
+                result.passwordHandle = new byte[handleLen];
+                buffer.get(result.passwordHandle);
+            } else {
+                result.passwordHandle = null;
+            }
+            return result;
+        }
+
+        public byte[] toBytes() {
+
+            ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + 3 * Byte.BYTES
+                    + Integer.BYTES + salt.length + Integer.BYTES +
+                    (passwordHandle != null ? passwordHandle.length : 0));
+            buffer.putInt(passwordType);
+            buffer.put(scryptN);
+            buffer.put(scryptR);
+            buffer.put(scryptP);
+            buffer.putInt(salt.length);
+            buffer.put(salt);
+            if (passwordHandle != null && passwordHandle.length > 0) {
+                buffer.putInt(passwordHandle.length);
+                buffer.put(passwordHandle);
+            } else {
+                buffer.putInt(0);
+            }
+            return buffer.array();
+        }
+    }
+
+    static class TokenData {
+        byte[] secdiscardableOnDisk;
+        byte[] weaverSecret;
+        byte[] aggregatedSecret;
+    }
+
+    private LockSettingsStorage mStorage;
+    private IWeaver mWeaver;
+    private WeaverConfig mWeaverConfig;
+
+    public SyntheticPasswordManager(LockSettingsStorage storage) {
+        mStorage = storage;
+    }
+
+    @VisibleForTesting
+    protected IWeaver getWeaverService() throws RemoteException {
+        try {
+            return IWeaver.getService();
+        } catch (NoSuchElementException e) {
+            Slog.i(TAG, "Device does not support weaver");
+            return null;
+        }
+    }
+
+    public synchronized void initWeaverService() {
+        if (mWeaver != null) {
+            return;
+        }
+        try {
+            mWeaverConfig = null;
+            mWeaver = getWeaverService();
+            if (mWeaver != null) {
+                mWeaver.getConfig((int status, WeaverConfig config) -> {
+                    if (status == WeaverStatus.OK && config.slots > 0) {
+                        mWeaverConfig = config;
+                    } else {
+                        Slog.e(TAG, "Failed to get weaver config, status " + status
+                                + " slots: " + config.slots);
+                        mWeaver = null;
+                    }
+                });
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get weaver service", e);
+        }
+    }
+
+    private synchronized boolean isWeaverAvailable() {
+        if (mWeaver == null) {
+            //Re-initializing weaver in case there was a transient error preventing access to it.
+            initWeaverService();
+        }
+        return mWeaver != null && mWeaverConfig.slots > 0;
+    }
+
+    /**
+     * Enroll the given key value pair into the specified weaver slot. if the given key is null,
+     * a default all-zero key is used. If the value is not specified, a fresh random secret is
+     * generated as the value.
+     *
+     * @return the value stored in the weaver slot
+     * @throws RemoteException
+     */
+    private byte[] weaverEnroll(int slot, byte[] key, @Nullable byte[] value)
+            throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        if (value == null) {
+            value = secureRandom(mWeaverConfig.valueSize);
+        }
+        int writeStatus = mWeaver.write(slot, toByteArrayList(key), toByteArrayList(value));
+        if (writeStatus != WeaverStatus.OK) {
+            Log.e(TAG, "weaver write failed, slot: " + slot + " status: " + writeStatus);
+            return null;
+        }
+        return value;
+    }
+
+    /**
+     * Verify the supplied key against a weaver slot, returning a response indicating whether
+     * the verification is successful, throttled or failed. If successful, the bound secret
+     * is also returned.
+     * @throws RemoteException
+     */
+    private VerifyCredentialResponse weaverVerify(int slot, byte[] key) throws RemoteException {
+        if (slot == INVALID_WEAVER_SLOT || slot >= mWeaverConfig.slots) {
+            throw new RuntimeException("Invalid slot for weaver");
+        }
+        if (key == null) {
+            key = new byte[mWeaverConfig.keySize];
+        } else if (key.length != mWeaverConfig.keySize) {
+            throw new RuntimeException("Invalid key size for weaver");
+        }
+        final VerifyCredentialResponse[] response = new VerifyCredentialResponse[1];
+        mWeaver.read(slot, toByteArrayList(key), (int status, WeaverReadResponse readResponse) -> {
+            switch (status) {
+                case WeaverReadStatus.OK:
+                    response[0] = new VerifyCredentialResponse(
+                            fromByteArrayList(readResponse.value));
+                    break;
+                case WeaverReadStatus.THROTTLE:
+                    response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                    Log.e(TAG, "weaver read failed (THROTTLE), slot: " + slot);
+                    break;
+                case WeaverReadStatus.INCORRECT_KEY:
+                    if (readResponse.timeout == 0) {
+                        response[0] = VerifyCredentialResponse.ERROR;
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY), slot: " + slot);
+                    } else {
+                        response[0] = new VerifyCredentialResponse(readResponse.timeout);
+                        Log.e(TAG, "weaver read failed (INCORRECT_KEY/THROTTLE), slot: " + slot);
+                    }
+                    break;
+                case WeaverReadStatus.FAILED:
+                    response[0] = VerifyCredentialResponse.ERROR;
+                    Log.e(TAG, "weaver read failed (FAILED), slot: " + slot);
+                    break;
+               default:
+                   response[0] = VerifyCredentialResponse.ERROR;
+                   Log.e(TAG, "weaver read unknown status " + status + ", slot: " + slot);
+                   break;
+            }
+        });
+        return response[0];
+    }
+
+    public void removeUser(int userId) {
+        if (isWeaverAvailable()) {
+            for (long handle : mStorage.listSyntheticPasswordHandlesForUser(WEAVER_SLOT_NAME,
+                    userId)) {
+                destroyWeaverSlot(handle, userId);
+            }
+        }
+    }
+
+    public int getCredentialType(long handle, int userId) {
+        byte[] passwordData = loadState(PASSWORD_DATA_NAME, handle, userId);
+        if (passwordData == null) {
+            Log.w(TAG, "getCredentialType: encountered empty password data for user " + userId);
+            return LockPatternUtils.CREDENTIAL_TYPE_NONE;
+        }
+        return PasswordData.fromBytes(passwordData).passwordType;
+    }
+
+    /**
+     * Initializing a new Authentication token, possibly from an existing credential and hash.
+     *
+     * The authentication token would bear a randomly-generated synthetic password.
+     *
+     * This method has the side effect of rebinding the SID of the given user to the
+     * newly-generated SP.
+     *
+     * If the existing credential hash is non-null, the existing SID mill be migrated so
+     * the synthetic password in the authentication token will produce the same SID
+     * (the corresponding synthetic password handle is persisted by SyntheticPasswordManager
+     * in a per-user data storage.)
+     *
+     * If the existing credential hash is null, it means the given user should have no SID so
+     * SyntheticPasswordManager will nuke any SP handle previously persisted. In this case,
+     * the supplied credential parameter is also ignored.
+     *
+     * Also saves the escrow information necessary to re-generate the synthetic password under
+     * an escrow scheme. This information can be removed with {@link #destroyEscrowData} if
+     * password escrow should be disabled completely on the given user.
+     *
+     */
+    public AuthenticationToken newSyntheticPasswordAndSid(IGateKeeperService gatekeeper,
+            byte[] hash, String credential, int userId) throws RemoteException {
+        AuthenticationToken result = AuthenticationToken.create();
+        GateKeeperResponse response;
+        if (hash != null) {
+            response = gatekeeper.enroll(userId, hash, credential.getBytes(),
+                    result.deriveGkPassword());
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.w(TAG, "Fail to migrate SID, assuming no SID, user " + userId);
+                clearSidForUser(userId);
+            } else {
+                saveSyntheticPasswordHandle(response.getPayload(), userId);
+            }
+        } else {
+            clearSidForUser(userId);
+        }
+        saveEscrowData(result, userId);
+        return result;
+    }
+
+    /**
+     * Enroll a new password handle and SID for the given synthetic password and persist it on disk.
+     * Used when adding password to previously-unsecured devices.
+     */
+    public void newSidForUser(IGateKeeperService gatekeeper, AuthenticationToken authToken,
+            int userId) throws RemoteException {
+        GateKeeperResponse response = gatekeeper.enroll(userId, null, null,
+                authToken.deriveGkPassword());
+        if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+            Log.e(TAG, "Fail to create new SID for user " + userId);
+            return;
+        }
+        saveSyntheticPasswordHandle(response.getPayload(), userId);
+    }
+
+    // Nuke the SP handle (and as a result, its SID) for the given user.
+    public void clearSidForUser(int userId) {
+        destroyState(SP_HANDLE_NAME, true, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasSidForUser(int userId) {
+        return hasState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    // if null, it means there is no SID associated with the user
+    // This can happen if the user is migrated to SP but currently
+    // do not have a lockscreen password.
+    private byte[] loadSyntheticPasswordHandle(int userId) {
+        return loadState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    private void saveSyntheticPasswordHandle(byte[] spHandle, int userId) {
+        saveState(SP_HANDLE_NAME, spHandle, DEFAULT_HANDLE, userId);
+    }
+
+    private boolean loadEscrowData(AuthenticationToken authToken, int userId) {
+        authToken.E0 = loadState(SP_E0_NAME, DEFAULT_HANDLE, userId);
+        authToken.P1 = loadState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+        return authToken.E0 != null && authToken.P1 != null;
+    }
+
+    private void saveEscrowData(AuthenticationToken authToken, int userId) {
+        saveState(SP_E0_NAME, authToken.E0, DEFAULT_HANDLE, userId);
+        saveState(SP_P1_NAME, authToken.P1, DEFAULT_HANDLE, userId);
+    }
+
+    public boolean hasEscrowData(int userId) {
+        return hasState(SP_E0_NAME, DEFAULT_HANDLE, userId)
+                && hasState(SP_P1_NAME, DEFAULT_HANDLE, userId);
+    }
+
+    public void destroyEscrowData(int userId) {
+        destroyState(SP_E0_NAME, true, DEFAULT_HANDLE, userId);
+        destroyState(SP_P1_NAME, true, DEFAULT_HANDLE, userId);
+    }
+
+    private int loadWeaverSlot(long handle, int userId) {
+        final int LENGTH = Byte.BYTES + Integer.BYTES;
+        byte[] data = loadState(WEAVER_SLOT_NAME, handle, userId);
+        if (data == null || data.length != LENGTH) {
+            return INVALID_WEAVER_SLOT;
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(LENGTH);
+        buffer.put(data, 0, data.length);
+        buffer.flip();
+        if (buffer.get() != WEAVER_VERSION) {
+            Log.e(TAG, "Invalid weaver slot version of handle " + handle);
+            return INVALID_WEAVER_SLOT;
+        }
+        return buffer.getInt();
+    }
+
+    private void saveWeaverSlot(int slot, long handle, int userId) {
+        ByteBuffer buffer = ByteBuffer.allocate(Byte.BYTES + Integer.BYTES);
+        buffer.put(WEAVER_VERSION);
+        buffer.putInt(slot);
+        saveState(WEAVER_SLOT_NAME, buffer.array(), handle, userId);
+    }
+
+    private void destroyWeaverSlot(long handle, int userId) {
+        int slot = loadWeaverSlot(handle, userId);
+        if (slot != INVALID_WEAVER_SLOT) {
+            try {
+                weaverEnroll(slot, null, null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to destroy slot", e);
+            }
+        }
+        destroyState(WEAVER_SLOT_NAME, true, handle, userId);
+    }
+
+    private int getNextAvailableWeaverSlot() {
+        Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
+                WEAVER_SLOT_NAME);
+        HashSet<Integer> slots = new HashSet<>();
+        for (Map.Entry<Integer, List<Long>> entry : slotHandles.entrySet()) {
+            for (Long handle : entry.getValue()) {
+                int slot = loadWeaverSlot(handle, entry.getKey());
+                slots.add(slot);
+            }
+        }
+        for (int i = 0; i < mWeaverConfig.slots; i++) {
+            if (!slots.contains(i)) {
+                return i;
+            }
+        }
+        throw new RuntimeException("Run out of weaver slots.");
+    }
+
+    /**
+     * Create a new password based SP blob based on the supplied authentication token, such that
+     * a future successful authentication with unwrapPasswordBasedSyntheticPassword() would result
+     * in the same authentication token.
+     *
+     * This method only creates SP blob wrapping around the given synthetic password and does not
+     * handle logic around SID or SP handle. The caller should separately ensure that the user's SID
+     * is consistent with the device state by calling other APIs in this class.
+     *
+     * @see #newSidForUser
+     * @see #clearSidForUser
+     */
+    public long createPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            String credential, int credentialType, AuthenticationToken authToken, int userId)
+                    throws RemoteException {
+        if (credential == null || credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+            credentialType = LockPatternUtils.CREDENTIAL_TYPE_NONE;
+            credential = DEFAULT_PASSWORD;
+        }
+
+        long handle = generateHandle();
+        PasswordData pwd = PasswordData.create(credentialType);
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+        final long sid;
+        final byte[] applicationId;
+
+        if (isWeaverAvailable()) {
+            // Weaver based user password
+            int weaverSlot = getNextAvailableWeaverSlot();
+            byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
+            if (weaverSecret == null) {
+                Log.e(TAG, "Fail to enroll user password under weaver " + userId);
+                return DEFAULT_HANDLE;
+            }
+            saveWeaverSlot(weaverSlot, handle, userId);
+
+            pwd.passwordHandle = null;
+            sid = GateKeeper.INVALID_SECURE_USER_ID;
+            applicationId = transformUnderWeaverSecret(pwdToken, weaverSecret);
+        } else {
+            // In case GK enrollment leaves persistent state around (in RPMB), this will nuke them
+            // to prevent them from accumulating and causing problems.
+            gatekeeper.clearSecureUserId(fakeUid(userId));
+            // GateKeeper based user password
+            GateKeeperResponse response = gatekeeper.enroll(fakeUid(userId), null, null,
+                    passwordTokenToGkInput(pwdToken));
+            if (response.getResponseCode() != GateKeeperResponse.RESPONSE_OK) {
+                Log.e(TAG, "Fail to enroll user password when creating SP for user " + userId);
+                return DEFAULT_HANDLE;
+            }
+            pwd.passwordHandle = response.getPayload();
+            sid = sidFromPasswordHandle(pwd.passwordHandle);
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    createSecdiscardable(handle, userId));
+        }
+        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, authToken,
+                applicationId, sid, userId);
+        return handle;
+    }
+
+    private ArrayMap<Integer, ArrayMap<Long, TokenData>> tokenMap = new ArrayMap<>();
+
+    public long createTokenBasedSyntheticPassword(byte[] token, int userId) {
+        long handle = generateHandle();
+        if (!tokenMap.containsKey(userId)) {
+            tokenMap.put(userId, new ArrayMap<>());
+        }
+        TokenData tokenData = new TokenData();
+        final byte[] secdiscardable = secureRandom(SECDISCARDABLE_LENGTH);
+        if (isWeaverAvailable()) {
+            tokenData.weaverSecret = secureRandom(mWeaverConfig.valueSize);
+            tokenData.secdiscardableOnDisk = SyntheticPasswordCrypto.encrypt(tokenData.weaverSecret,
+                            PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        } else {
+            tokenData.secdiscardableOnDisk = secdiscardable;
+            tokenData.weaverSecret = null;
+        }
+        tokenData.aggregatedSecret = transformUnderSecdiscardable(token, secdiscardable);
+
+        tokenMap.get(userId).put(handle, tokenData);
+        return handle;
+    }
+
+    public Set<Long> getPendingTokensForUser(int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return Collections.emptySet();
+        }
+        return tokenMap.get(userId).keySet();
+    }
+
+    public boolean removePendingToken(long handle, int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        return tokenMap.get(userId).remove(handle) != null;
+    }
+
+    public boolean activateTokenBasedSyntheticPassword(long handle, AuthenticationToken authToken,
+            int userId) {
+        if (!tokenMap.containsKey(userId)) {
+            return false;
+        }
+        TokenData tokenData = tokenMap.get(userId).get(handle);
+        if (tokenData == null) {
+            return false;
+        }
+        if (!loadEscrowData(authToken, userId)) {
+            Log.w(TAG, "User is not escrowable");
+            return false;
+        }
+        if (isWeaverAvailable()) {
+            int slot = getNextAvailableWeaverSlot();
+            try {
+                weaverEnroll(slot, null, tokenData.weaverSecret);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to enroll weaver secret when activating token", e);
+                return false;
+            }
+            saveWeaverSlot(slot, handle, userId);
+        }
+        saveSecdiscardable(handle, tokenData.secdiscardableOnDisk, userId);
+        createSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, authToken,
+                tokenData.aggregatedSecret, 0L, userId);
+        tokenMap.get(userId).remove(handle);
+        return true;
+    }
+
+    private void createSyntheticPasswordBlob(long handle, byte type, AuthenticationToken authToken,
+            byte[] applicationId, long sid, int userId) {
+        final byte[] secret;
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            secret = authToken.computeP0();
+        } else {
+            secret = authToken.syntheticPassword.getBytes();
+        }
+        byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid);
+        byte[] blob = new byte[content.length + 1 + 1];
+        blob[0] = SYNTHETIC_PASSWORD_VERSION;
+        blob[1] = type;
+        System.arraycopy(content, 0, blob, 2, content.length);
+        saveState(SP_BLOB_NAME, blob, handle, userId);
+    }
+
+    /**
+     * Decrypt a synthetic password by supplying the user credential and corresponding password
+     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
+     * verification to referesh the SID & Auth token maintained by the system.
+     */
+    public AuthenticationResult unwrapPasswordBasedSyntheticPassword(IGateKeeperService gatekeeper,
+            long handle, String credential, int userId) throws RemoteException {
+        if (credential == null) {
+            credential = DEFAULT_PASSWORD;
+        }
+        AuthenticationResult result = new AuthenticationResult();
+        PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, handle, userId));
+        byte[] pwdToken = computePasswordToken(credential, pwd);
+
+        final byte[] applicationId;
+        int weaverSlot = loadWeaverSlot(handle, userId);
+        if (weaverSlot != INVALID_WEAVER_SLOT) {
+            // Weaver based user password
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap password based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            result.gkResponse = weaverVerify(weaverSlot, passwordTokenToWeaverKey(pwdToken));
+            if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+                return result;
+            }
+            applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload());
+        } else {
+            byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
+            GateKeeperResponse response = gatekeeper.verifyChallenge(fakeUid(userId), 0L,
+                    pwd.passwordHandle, gkPwdToken);
+            int responseCode = response.getResponseCode();
+            if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+                result.gkResponse = VerifyCredentialResponse.OK;
+                if (response.getShouldReEnroll()) {
+                    GateKeeperResponse reenrollResponse = gatekeeper.enroll(fakeUid(userId),
+                            pwd.passwordHandle, gkPwdToken, gkPwdToken);
+                    if (reenrollResponse.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                        pwd.passwordHandle = reenrollResponse.getPayload();
+                        saveState(PASSWORD_DATA_NAME, pwd.toBytes(), handle, userId);
+                    } else {
+                        Log.w(TAG, "Fail to re-enroll user password for user " + userId);
+                        // continue the flow anyway
+                    }
+                }
+            } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+                result.gkResponse = new VerifyCredentialResponse(response.getTimeout());
+                return result;
+            } else  {
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            applicationId = transformUnderSecdiscardable(pwdToken,
+                    loadSecdiscardable(handle, userId));
+        }
+
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
+                applicationId, userId);
+
+        // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
+        result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+        return result;
+    }
+
+    /**
+     * Decrypt a synthetic password by supplying an escrow token and corresponding token
+     * blob handle generated previously. If the decryption is successful, initiate a GateKeeper
+     * verification to referesh the SID & Auth token maintained by the system.
+     */
+    public @NonNull AuthenticationResult unwrapTokenBasedSyntheticPassword(
+            IGateKeeperService gatekeeper, long handle, byte[] token, int userId)
+                    throws RemoteException {
+        AuthenticationResult result = new AuthenticationResult();
+        byte[] secdiscardable = loadSecdiscardable(handle, userId);
+        int slotId = loadWeaverSlot(handle, userId);
+        if (slotId != INVALID_WEAVER_SLOT) {
+            if (!isWeaverAvailable()) {
+                Log.e(TAG, "No weaver service to unwrap token based SP");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            VerifyCredentialResponse response = weaverVerify(slotId, null);
+            if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK ||
+                    response.getPayload() == null) {
+                Log.e(TAG, "Failed to retrieve weaver secret when unwrapping token");
+                result.gkResponse = VerifyCredentialResponse.ERROR;
+                return result;
+            }
+            secdiscardable = SyntheticPasswordCrypto.decrypt(response.getPayload(),
+                    PERSONALISATION_WEAVER_TOKEN, secdiscardable);
+        }
+        byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
+        result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
+                applicationId, userId);
+        if (result.authToken != null) {
+            result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
+            if (result.gkResponse == null) {
+                // The user currently has no password. return OK with null payload so null
+                // is propagated to unlockUser()
+                result.gkResponse = VerifyCredentialResponse.OK;
+            }
+        } else {
+            result.gkResponse = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
+            byte[] applicationId, int userId) {
+        byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
+        if (blob == null) {
+            return null;
+        }
+        if (blob[0] != SYNTHETIC_PASSWORD_VERSION) {
+            throw new RuntimeException("Unknown blob version");
+        }
+        if (blob[1] != type) {
+            throw new RuntimeException("Invalid blob type");
+        }
+        byte[] secret = decryptSPBlob(getHandleName(handle),
+                Arrays.copyOfRange(blob, 2, blob.length), applicationId);
+        if (secret == null) {
+            Log.e(TAG, "Fail to decrypt SP for user " + userId);
+            return null;
+        }
+        AuthenticationToken result = new AuthenticationToken();
+        if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) {
+            if (!loadEscrowData(result, userId)) {
+                Log.e(TAG, "User is not escrowable: " + userId);
+                return null;
+            }
+            result.recreate(secret);
+        } else {
+            result.syntheticPassword = new String(secret);
+        }
+        return result;
+    }
+
+    /**
+     * performs GK verifyChallenge and returns auth token, re-enrolling SP password handle
+     * if required.
+     *
+     * Normally performing verifyChallenge with an AuthenticationToken should always return
+     * RESPONSE_OK, since user authentication failures are detected earlier when trying to
+     * decrypt SP.
+     */
+    public @Nullable VerifyCredentialResponse verifyChallenge(IGateKeeperService gatekeeper,
+            @NonNull AuthenticationToken auth, long challenge, int userId) throws RemoteException {
+        byte[] spHandle = loadSyntheticPasswordHandle(userId);
+        if (spHandle == null) {
+            // There is no password handle associated with the given user, i.e. the user is not
+            // secured by lockscreen and has no SID, so just return here;
+            return null;
+        }
+        VerifyCredentialResponse result;
+        GateKeeperResponse response = gatekeeper.verifyChallenge(userId, challenge,
+                spHandle, auth.deriveGkPassword());
+        int responseCode = response.getResponseCode();
+        if (responseCode == GateKeeperResponse.RESPONSE_OK) {
+            result = new VerifyCredentialResponse(response.getPayload());
+            if (response.getShouldReEnroll()) {
+                response = gatekeeper.enroll(userId, spHandle,
+                        spHandle, auth.deriveGkPassword());
+                if (response.getResponseCode() == GateKeeperResponse.RESPONSE_OK) {
+                    spHandle = response.getPayload();
+                    saveSyntheticPasswordHandle(spHandle, userId);
+                    // Call self again to re-verify with updated handle
+                    return verifyChallenge(gatekeeper, auth, challenge, userId);
+                } else {
+                    Log.w(TAG, "Fail to re-enroll SP handle for user " + userId);
+                    // Fall through, return existing handle
+                }
+            }
+        } else if (responseCode == GateKeeperResponse.RESPONSE_RETRY) {
+            result = new VerifyCredentialResponse(response.getTimeout());
+        } else {
+            result = VerifyCredentialResponse.ERROR;
+        }
+        return result;
+    }
+
+    public boolean existsHandle(long handle, int userId) {
+        return hasState(SP_BLOB_NAME, handle, userId);
+    }
+
+    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
+    }
+
+    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
+        destroySyntheticPassword(handle, userId);
+        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
+        destroyState(PASSWORD_DATA_NAME, true, handle, userId);
+    }
+
+    private void destroySyntheticPassword(long handle, int userId) {
+        destroyState(SP_BLOB_NAME, true, handle, userId);
+        destroySPBlobKey(getHandleName(handle));
+        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
+            destroyWeaverSlot(handle, userId);
+        }
+    }
+
+    private byte[] transformUnderWeaverSecret(byte[] data, byte[] secret) {
+        byte[] weaverSecret = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_WEAVER_PASSWORD, secret);
+        byte[] result = new byte[data.length + weaverSecret.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(weaverSecret, 0, result, data.length, weaverSecret.length);
+        return result;
+    }
+
+    private byte[] transformUnderSecdiscardable(byte[] data, byte[] rawSecdiscardable) {
+        byte[] secdiscardable = SyntheticPasswordCrypto.personalisedHash(
+                PERSONALISATION_SECDISCARDABLE, rawSecdiscardable);
+        byte[] result = new byte[data.length + secdiscardable.length];
+        System.arraycopy(data, 0, result, 0, data.length);
+        System.arraycopy(secdiscardable, 0, result, data.length, secdiscardable.length);
+        return result;
+    }
+
+    private byte[] createSecdiscardable(long handle, int userId) {
+        byte[] data = secureRandom(SECDISCARDABLE_LENGTH);
+        saveSecdiscardable(handle, data, userId);
+        return data;
+    }
+
+    private void saveSecdiscardable(long handle, byte[] secdiscardable, int userId) {
+        saveState(SECDISCARDABLE_NAME, secdiscardable, handle, userId);
+    }
+
+    private byte[] loadSecdiscardable(long handle, int userId) {
+        return loadState(SECDISCARDABLE_NAME, handle, userId);
+    }
+
+    private boolean hasState(String stateName, long handle, int userId) {
+        return !ArrayUtils.isEmpty(loadState(stateName, handle, userId));
+    }
+
+    private byte[] loadState(String stateName, long handle, int userId) {
+        return mStorage.readSyntheticPasswordState(userId, handle, stateName);
+    }
+
+    private void saveState(String stateName, byte[] data, long handle, int userId) {
+        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
+    }
+
+    private void destroyState(String stateName, boolean secure, long handle, int userId) {
+        mStorage.deleteSyntheticPasswordState(userId, handle, stateName, secure);
+    }
+
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        return SyntheticPasswordCrypto.decryptBlob(blobKeyName, blob, applicationId);
+    }
+
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        return SyntheticPasswordCrypto.createBlob(blobKeyName, data, applicationId, sid);
+    }
+
+    protected void destroySPBlobKey(String keyAlias) {
+        SyntheticPasswordCrypto.destroyBlobKey(keyAlias);
+    }
+
+    public static long generateHandle() {
+        SecureRandom rng = new SecureRandom();
+        long result;
+        do {
+            result = rng.nextLong();
+        } while (result == DEFAULT_HANDLE);
+        return result;
+    }
+
+    private int fakeUid(int uid) {
+        return 100000 + uid;
+    }
+
+    protected static byte[] secureRandom(int length) {
+        try {
+            return SecureRandom.getInstance("SHA1PRNG").generateSeed(length);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private String getHandleName(long handle) {
+        return String.format("%s%x", LockPatternUtils.SYNTHETIC_PASSWORD_KEY_PREFIX, handle);
+    }
+
+    private byte[] computePasswordToken(String password, PasswordData data) {
+        return scrypt(password, data.salt, 1 << data.scryptN, 1 << data.scryptR, 1 << data.scryptP,
+                PASSWORD_TOKEN_LENGTH);
+    }
+
+    private byte[] passwordTokenToGkInput(byte[] token) {
+        return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_USER_GK_AUTH, token);
+    }
+
+    private byte[] passwordTokenToWeaverKey(byte[] token) {
+        byte[] key = SyntheticPasswordCrypto.personalisedHash(PERSONALISATION_WEAVER_KEY, token);
+        if (key.length < mWeaverConfig.keySize) {
+            throw new RuntimeException("weaver key length too small");
+        }
+        return Arrays.copyOf(key, mWeaverConfig.keySize);
+    }
+
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return nativeSidFromPasswordHandle(handle);
+    }
+
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
+    }
+
+    native long nativeSidFromPasswordHandle(byte[] handle);
+    native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
+
+    protected static ArrayList<Byte> toByteArrayList(byte[] data) {
+        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
+        for (int i = 0; i < data.length; i++) {
+            result.add(data[i]);
+        }
+        return result;
+    }
+
+    protected static byte[] fromByteArrayList(ArrayList<Byte> data) {
+        byte[] result = new byte[data.size()];
+        for (int i = 0; i < data.size(); i++) {
+            result[i] = data.get(i);
+        }
+        return result;
+    }
+
+    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
+    public static String bytesToHex(byte[] bytes) {
+        if (bytes == null) {
+            return "null";
+        }
+        char[] hexChars = new char[bytes.length * 2];
+        for ( int j = 0; j < bytes.length; j++ ) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = hexArray[v >>> 4];
+            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 8caaaa1..4c00921 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -48,8 +48,8 @@
     @Override
     public int compare(NotificationRecord left, NotificationRecord right) {
         // first all colorized notifications
-        boolean leftImportantColorized = isImportantOngoingColorized(left);
-        boolean rightImportantColorized = isImportantOngoingColorized(right);
+        boolean leftImportantColorized = isImportantColorized(left);
+        boolean rightImportantColorized = isImportantColorized(right);
 
         if (leftImportantColorized != rightImportantColorized) {
             return -1 * Boolean.compare(leftImportantColorized, rightImportantColorized);
@@ -117,10 +117,7 @@
         return -1 * Long.compare(left.getRankingTimeMs(), right.getRankingTimeMs());
     }
 
-    private boolean isImportantOngoingColorized(NotificationRecord record) {
-        if (!isOngoing(record)) {
-            return false;
-        }
+    private boolean isImportantColorized(NotificationRecord record) {
         if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
             return false;
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1d843c1..23a1a78 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -96,6 +96,7 @@
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
 import android.media.IRingtonePlayer;
+import android.media.ToneGenerator;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -301,6 +302,10 @@
     private boolean mInCall = false;
     private boolean mNotificationPulseEnabled;
 
+    // for generating notification tones in-call
+    private ToneGenerator mInCallToneGenerator;
+    private final Object mInCallToneGeneratorLock = new Object();
+
     // used as a mutex for access to all active notifications & listeners
     final Object mNotificationLock = new Object();
     final ArrayList<NotificationRecord> mNotificationList =
@@ -854,6 +859,30 @@
                 mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
                         .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                 updateNotificationPulse();
+                synchronized (mInCallToneGeneratorLock) {
+                    if (mInCall) {
+                        if (mInCallToneGenerator == null) {
+                            int relativeToneVolume = getContext().getResources().getInteger(
+                                    R.integer.config_inCallNotificationVolumeRelative);
+                            if (relativeToneVolume < ToneGenerator.MIN_VOLUME
+                                    || relativeToneVolume > ToneGenerator.MAX_VOLUME) {
+                                relativeToneVolume = ToneGenerator.MAX_VOLUME;
+                            }
+                            try {
+                                mInCallToneGenerator = new ToneGenerator(
+                                        AudioManager.STREAM_VOICE_CALL, relativeToneVolume);
+                            } catch (RuntimeException e) {
+                                Log.e(TAG, "Error creating local tone generator: " + e);
+                                mInCallToneGenerator = null;
+                            }
+                        }
+                    } else {
+                        if (mInCallToneGenerator != null) {
+                            mInCallToneGenerator.release();
+                            mInCallToneGenerator = null;
+                        }
+                     }
+                }
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
@@ -2871,8 +2900,7 @@
                                 adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY,
                                 System.currentTimeMillis());
                 summaryRecord = new NotificationRecord(getContext(), summarySbn,
-                        notificationRecord.getChannel(), mRankingHelper.supportsChannels(
-                                summarySbn.getPackageName(), summarySbn.getUid()));
+                        notificationRecord.getChannel());
                 summaries.put(pkg, summarySbn.getKey());
             }
         }
@@ -3211,8 +3239,7 @@
         final StatusBarNotification n = new StatusBarNotification(
                 pkg, opPkg, id, tag, notificationUid, callingPid, notification,
                 user, null, System.currentTimeMillis());
-        final NotificationRecord r = new NotificationRecord(getContext(), n, channel,
-                mRankingHelper.supportsChannels(pkg, notificationUid));
+        final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
 
         if (!checkDisqualifyingFeatures(userId, notificationUid, id,tag, r)) {
             return;
@@ -3725,14 +3752,21 @@
             hasValidVibrate = vibration != null;
 
             if (!shouldMuteNotificationLocked(record)) {
-
                 sendAccessibilityEvent(notification, record.sbn.getPackageName());
+
                 if (hasValidSound) {
                     mSoundNotificationKey = key;
-                    beep = playSound(record, soundUri);
+                    if (mInCall) {
+                        playInCallNotification();
+                        beep = true;
+                    } else {
+                        beep = playSound(record, soundUri);
+                    }
                 }
-                if (hasValidVibrate && !(mAudioManager.getRingerModeInternal()
-                        == AudioManager.RINGER_MODE_SILENT)) {
+
+                final boolean ringerModeSilent =
+                        mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
+                if (!mInCall && hasValidVibrate && !ringerModeSilent) {
                     mVibrateNotificationKey = key;
 
                     buzz = playVibration(record, vibration);
@@ -3841,6 +3875,26 @@
         }
     }
 
+    private void playInCallNotification() {
+        new Thread() {
+            @Override
+            public void run() {
+                // If toneGenerator creation fails, just continue the call
+                // without playing the notification sound.
+                try {
+                    synchronized (mInCallToneGeneratorLock) {
+                        if (mInCallToneGenerator != null) {
+                            // limit this tone to 1 second; BEEP2 should in fact be much shorter
+                            mInCallToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2, 1000);
+                        }
+                    }
+                } catch (RuntimeException e) {
+                    Log.w(TAG, "Exception from ToneGenerator: " + e);
+                }
+            }
+        }.start();
+    }
+
     void showNextToastLocked() {
         ToastRecord record = mToastQueue.get(0);
         while (record != null) {
@@ -3937,7 +3991,7 @@
             }
         }
         try {
-            mAm.setProcessForeground(mForegroundToken, pid, toastCount > 0);
+            mAm.setProcessImportant(mForegroundToken, pid, toastCount > 0, "toast");
         } catch (RemoteException e) {
             // Shouldn't happen.
         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index f019a5c..5a5e658 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -116,7 +116,7 @@
     private int mSuppressedVisualEffects = 0;
     private String mUserExplanation;
     private String mPeopleExplanation;
-    private boolean mSupportsChannels = false;
+    private boolean mPreChannelsNotification = true;
     private Uri mSound;
     private long[] mVibration;
     private AudioAttributes mAttributes;
@@ -129,7 +129,7 @@
 
     @VisibleForTesting
     public NotificationRecord(Context context, StatusBarNotification sbn,
-            NotificationChannel channel, boolean supportsChannels)
+            NotificationChannel channel)
     {
         this.sbn = sbn;
         mOriginalFlags = sbn.getNotification().flags;
@@ -139,7 +139,7 @@
         mContext = context;
         stats = new NotificationUsageStats.SingleNotificationStats();
         mChannel = channel;
-        mSupportsChannels = supportsChannels;
+        mPreChannelsNotification = isPreChannelsNotification();
         mSound = calculateSound();
         mVibration = calculateVibration();
         mAttributes = calculateAttributes();
@@ -147,11 +147,27 @@
         mLight = calculateLights();
     }
 
+    private boolean isPreChannelsNotification() {
+        try {
+            if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(getChannel().getId())) {
+                  final ApplicationInfo applicationInfo =
+                        mContext.getPackageManager().getApplicationInfoAsUser(sbn.getPackageName(),
+                                0, UserHandle.getUserId(sbn.getUid()));
+                if (applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+                    return true;
+                }
+            }
+        } catch (NameNotFoundException e) {
+            Slog.e(TAG, "Can't find package", e);
+        }
+        return false;
+    }
+
     private Uri calculateSound() {
         final Notification n = sbn.getNotification();
 
         Uri sound = mChannel.getSound();
-        if (!mSupportsChannels && (getChannel().getUserLockedFields()
+        if (mPreChannelsNotification && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_SOUND) == 0) {
 
             final boolean useDefaultSound = (n.defaults & Notification.DEFAULT_SOUND) != 0;
@@ -176,7 +192,7 @@
                 : defaultLightColor;
         Light light = getChannel().shouldShowLights() ? new Light(channelLightColor,
                 defaultLightOn, defaultLightOff) : null;
-        if (!mSupportsChannels
+        if (mPreChannelsNotification
                 && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_LIGHTS) == 0) {
             final Notification notification = sbn.getNotification();
@@ -207,7 +223,7 @@
         } else {
             vibration = null;
         }
-        if (!mSupportsChannels
+        if (mPreChannelsNotification
                 && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_VIBRATION) == 0) {
             final Notification notification = sbn.getNotification();
@@ -229,7 +245,7 @@
             attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
         }
 
-        if (!mSupportsChannels
+        if (mPreChannelsNotification
                 && (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_SOUND) == 0) {
             if (n.audioAttributes != null) {
@@ -278,7 +294,7 @@
         stats.requestedImportance = requestedImportance;
         stats.isNoisy = mSound != null || mVibration != null;
 
-        if (!mSupportsChannels
+        if (mPreChannelsNotification
                 && (importance == IMPORTANCE_UNSPECIFIED
                 || (getChannel().getUserLockedFields()
                 & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0)) {
@@ -445,7 +461,7 @@
         pw.println(prefix + "mVisibleSinceMs=" + mVisibleSinceMs);
         pw.println(prefix + "mUpdateTimeMs=" + mUpdateTimeMs);
         pw.println(prefix + "mSuppressedVisualEffects= " + mSuppressedVisualEffects);
-        if (!mSupportsChannels) {
+        if (mPreChannelsNotification) {
             pw.println(prefix + String.format("defaults=0x%08x flags=0x%08x",
                     notification.defaults, notification.flags));
             pw.println(prefix + "n.sound=" + notification.sound);
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 14d796f..4d19b52 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -42,6 +42,4 @@
     void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId);
     void permanentlyDeleteNotificationChannels(String pkg, int uid);
     ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid, boolean includeDeleted);
-
-    boolean supportsChannels(String pkg, int uid);
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 1e741de..7758516 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -273,14 +273,8 @@
     }
 
     private boolean shouldHaveDefaultChannel(Record r) throws NameNotFoundException {
-        if (supportsChannels(r)) {
-            return false;
-        }
-
         final int userId = UserHandle.getUserId(r.uid);
-        final ApplicationInfo applicationInfo = mPm.getApplicationInfoAsUser(r.pkg,
-                PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                userId);
+        final ApplicationInfo applicationInfo = mPm.getApplicationInfoAsUser(r.pkg, 0, userId);
         if (applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
             // O apps should not have the default channel.
             return false;
@@ -506,31 +500,6 @@
     }
 
     @Override
-    public boolean supportsChannels(String pkg, int uid) {
-        Record r = getOrCreateRecord(pkg, uid);
-
-        if (r == null) {
-            return false;
-        }
-
-        if (r.channels.size() == 1
-                && r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean supportsChannels(Record r) {
-        if (r.channels.size() == 1
-                && r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) {
-            return false;
-        }
-
-        return (r.channels.size() > 0);
-    }
-
-    @Override
     public void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
             boolean fromTargetApp) {
         Preconditions.checkNotNull(pkg);
@@ -602,10 +571,6 @@
         r.channels.put(channel.getId(), channel);
         MetricsLogger.action(getChannelLog(channel, pkg).setType(
                 MetricsProto.MetricsEvent.TYPE_OPEN));
-
-        // Remove Default Channel.
-        r.channels.remove(NotificationChannel.DEFAULT_CHANNEL_ID);
-
         updateConfig();
     }
 
@@ -702,7 +667,13 @@
         if (r == null) {
             return;
         }
-        r.channels.clear();
+        int N = r.channels.size() - 1;
+        for (int i = N; i >= 0; i--) {
+            String key = r.channels.keyAt(i);
+            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(key)) {
+                r.channels.remove(key);
+            }
+        }
         updateConfig();
     }
 
@@ -1066,8 +1037,6 @@
                 final int uid = uidList[i];
                 synchronized (mRecords) {
                     mRecords.remove(recordKey(pkg, uid));
-                    // reset to default settings and re-add misc channel for pre-O apps
-                    getOrCreateRecord(pkg, uid);
                 }
                 mRestoredWithoutUids.remove(pkg);
                 updated = true;
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 09e9433..aa780cc 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -80,19 +80,23 @@
     }
 
     public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[],
-            String token) {
+            String token) throws ConnectionException {
         throwIfCalledOnMainThread();
         IInstantAppResolver target = null;
         try {
-            target = getRemoteInstanceLazy(token);
-            return mGetEphemeralResolveInfoCaller
-                    .getEphemeralResolveInfoList(target, hashPrefix, token);
-        } catch (RemoteException e) {
-        } catch (InterruptedException | TimeoutException e) {
-            if (target == null) {
-                Slog.w(TAG, "[" + token + "] Timeout! Phase1 binding to instant app resolver");
-            } else {
-                Slog.w(TAG, "[" + token + "] Timeout! Phase1 resolving instant app");
+            try {
+                target = getRemoteInstanceLazy(token);
+            } catch (TimeoutException e) {
+                throw new ConnectionException(ConnectionException.FAILURE_BIND);
+            } catch (InterruptedException e) {
+                throw new ConnectionException(ConnectionException.FAILURE_INTERRUPTED);
+            }
+            try {
+                return mGetEphemeralResolveInfoCaller
+                        .getEphemeralResolveInfoList(target, hashPrefix, token);
+            } catch (TimeoutException e) {
+                throw new ConnectionException(ConnectionException.FAILURE_BIND);
+            } catch (RemoteException ignore) {
             }
         } finally {
             synchronized (mLock) {
@@ -104,7 +108,7 @@
 
     public final void getInstantAppIntentFilterList(int hashPrefix[], String token,
             String hostName, PhaseTwoCallback callback, Handler callbackHandler,
-            final long startTime) {
+            final long startTime) throws ConnectionException {
         final IRemoteCallback remoteCallback = new IRemoteCallback.Stub() {
             @Override
             public void sendResult(Bundle data) throws RemoteException {
@@ -122,14 +126,16 @@
         try {
             getRemoteInstanceLazy(token)
                     .getInstantAppIntentFilterList(hashPrefix, token, hostName, remoteCallback);
-        } catch (RemoteException e) {
-        } catch (InterruptedException | TimeoutException e) {
-            Slog.w(TAG, "[" + token + "] Timeout! Phase2 binding to instant app resolver");
+        } catch (TimeoutException e) {
+            throw new ConnectionException(ConnectionException.FAILURE_BIND);
+        } catch (InterruptedException e) {
+            throw new ConnectionException(ConnectionException.FAILURE_INTERRUPTED);
+        } catch (RemoteException ignore) {
         }
     }
 
     private IInstantAppResolver getRemoteInstanceLazy(String token)
-            throws TimeoutException, InterruptedException {
+            throws ConnectionException, TimeoutException, InterruptedException {
         synchronized (mLock) {
             if (mRemoteInstance != null) {
                 return mRemoteInstance;
@@ -139,7 +145,7 @@
         }
     }
 
-    private void waitForBind(String token) throws TimeoutException, InterruptedException {
+    private void waitForBindLocked(String token) throws TimeoutException, InterruptedException {
         final long startMillis = SystemClock.uptimeMillis();
         while (mIsBinding) {
             if (mRemoteInstance != null) {
@@ -154,12 +160,13 @@
         }
     }
 
-    private void bindLocked(String token) throws TimeoutException, InterruptedException {
+    private void bindLocked(String token)
+            throws ConnectionException, TimeoutException, InterruptedException {
         if (DEBUG_EPHEMERAL && mIsBinding && mRemoteInstance == null) {
             Slog.i(TAG, "[" + token + "] Previous bind timed out; waiting for connection");
         }
         try {
-            waitForBind(token);
+            waitForBindLocked(token);
         } catch (TimeoutException e) {
             if (DEBUG_EPHEMERAL) {
                 Slog.i(TAG, "[" + token + "] Previous connection never established; rebinding");
@@ -179,9 +186,10 @@
             wasBound = mContext
                     .bindServiceAsUser(mIntent, mServiceConnection, flags, UserHandle.SYSTEM);
             if (wasBound) {
-                waitForBind(token);
+                waitForBindLocked(token);
             } else {
                 Slog.w(TAG, "[" + token + "] Failed to bind to: " + mIntent);
+                throw new ConnectionException(ConnectionException.FAILURE_BIND);
             }
         } finally {
             mIsBinding = wasBound && mRemoteInstance == null;
@@ -222,6 +230,17 @@
                 List<InstantAppResolveInfo> instantAppResolveInfoList, long startTime);
     }
 
+    public static class ConnectionException extends Exception {
+        public static final int FAILURE_BIND = 1;
+        public static final int FAILURE_CALL = 2;
+        public static final int FAILURE_INTERRUPTED = 3;
+
+        public final int failure;
+        public ConnectionException(int _failure) {
+            failure = _failure;
+        }
+    }
+
     private final class MyServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c5cefc8..e6e4617 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -42,22 +42,20 @@
      * **************************************************************************/
     /** Application should be visible to everyone */
     public static final int DEXOPT_PUBLIC         = 1 << 1;
-    /** Application wants to run in VM safe mode */
-    public static final int DEXOPT_SAFEMODE       = 1 << 2;
     /** Application wants to allow debugging of its code */
-    public static final int DEXOPT_DEBUGGABLE     = 1 << 3;
+    public static final int DEXOPT_DEBUGGABLE     = 1 << 2;
     /** The system boot has finished */
-    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 4;
+    public static final int DEXOPT_BOOTCOMPLETE   = 1 << 3;
     /** Hint that the dexopt type is profile-guided. */
-    public static final int DEXOPT_PROFILE_GUIDED = 1 << 5;
+    public static final int DEXOPT_PROFILE_GUIDED = 1 << 4;
     /** The compilation is for a secondary dex file. */
-    public static final int DEXOPT_SECONDARY_DEX  = 1 << 6;
+    public static final int DEXOPT_SECONDARY_DEX  = 1 << 5;
     /** Ignore the result of dexoptNeeded and force compilation. */
-    public static final int DEXOPT_FORCE          = 1 << 7;
+    public static final int DEXOPT_FORCE          = 1 << 6;
     /** Indicates that the dex file passed to dexopt in on CE storage. */
-    public static final int DEXOPT_STORAGE_CE     = 1 << 8;
+    public static final int DEXOPT_STORAGE_CE     = 1 << 7;
     /** Indicates that the dex file passed to dexopt in on DE storage. */
-    public static final int DEXOPT_STORAGE_DE     = 1 << 9;
+    public static final int DEXOPT_STORAGE_DE     = 1 << 8;
 
     // NOTE: keep in sync with installd
     public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index f3c9cbb..85be4a2 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -22,6 +22,7 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_RESOLUTION_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_RESOLUTION_STATUS;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -50,20 +51,37 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.server.pm.EphemeralResolverConnection.ConnectionException;
 import com.android.server.pm.EphemeralResolverConnection.PhaseTwoCallback;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.TimeoutException;
 
 /** @hide */
 public abstract class InstantAppResolver {
     private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
     private static final String TAG = "PackageManager";
 
-    private static int RESOLUTION_SUCCESS = 0;
-    private static int RESOLUTION_FAILURE = 1;
+    private static final int RESOLUTION_SUCCESS = 0;
+    private static final int RESOLUTION_FAILURE = 1;
+    /** Binding to the external service timed out */
+    private static final int RESOLUTION_BIND_TIMEOUT = 2;
+    /** The call to retrieve an instant application response timed out */
+    private static final int RESOLUTION_CALL_TIMEOUT = 3;
+
+    @IntDef(flag = true, prefix = { "RESOLUTION_" }, value = {
+            RESOLUTION_SUCCESS,
+            RESOLUTION_FAILURE,
+            RESOLUTION_BIND_TIMEOUT,
+            RESOLUTION_CALL_TIMEOUT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResolutionStatus {}
 
     private static MetricsLogger sMetricsLogger;
     private static MetricsLogger getLogger() {
@@ -78,29 +96,43 @@
         final long startTime = System.currentTimeMillis();
         final String token = UUID.randomUUID().toString();
         if (DEBUG_EPHEMERAL) {
-            Log.d(TAG, "[" + token + "] Resolving phase 1");
+            Log.d(TAG, "[" + token + "] Phase1; resolving");
         }
         final Intent intent = requestObj.origIntent;
         final InstantAppDigest digest =
                 new InstantAppDigest(intent.getData().getHost(), 5 /*maxDigests*/);
         final int[] shaPrefix = digest.getDigestPrefix();
-        final List<InstantAppResolveInfo> instantAppResolveInfoList =
-                connection.getInstantAppResolveInfoList(shaPrefix, token);
-
-        if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) {
-            // No hash prefix match; there are no instant apps for this domain.
-            if (DEBUG_EPHEMERAL) {
-                Log.d(TAG, "[" + token + "] No results returned");
+        AuxiliaryResolveInfo resolveInfo = null;
+        @ResolutionStatus int resolutionStatus = RESOLUTION_SUCCESS;
+        try {
+            final List<InstantAppResolveInfo> instantAppResolveInfoList =
+                    connection.getInstantAppResolveInfoList(shaPrefix, token);
+            if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
+                resolveInfo = InstantAppResolver.filterInstantAppIntent(
+                        instantAppResolveInfoList, intent, requestObj.resolvedType,
+                        requestObj.userId, intent.getPackage(), digest, token);
             }
-            return null;
+        } catch (ConnectionException e) {
+            if (e.failure == ConnectionException.FAILURE_BIND) {
+                resolutionStatus = RESOLUTION_BIND_TIMEOUT;
+            } else if (e.failure == ConnectionException.FAILURE_CALL) {
+                resolutionStatus = RESOLUTION_CALL_TIMEOUT;
+            } else {
+                resolutionStatus = RESOLUTION_FAILURE;
+            }
         }
-        final AuxiliaryResolveInfo resolveInfo = InstantAppResolver.filterInstantAppIntent(
-                instantAppResolveInfoList, intent, requestObj.resolvedType, requestObj.userId,
-                intent.getPackage(), digest, token);
         logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token,
-                RESOLUTION_SUCCESS);
+                resolutionStatus);
         if (DEBUG_EPHEMERAL && resolveInfo == null) {
-            Log.d(TAG, "[" + token + "] No results matched");
+            if (resolutionStatus == RESOLUTION_BIND_TIMEOUT) {
+                Log.d(TAG, "[" + token + "] Phase1; bind timed out");
+            } else if (resolutionStatus == RESOLUTION_CALL_TIMEOUT) {
+                Log.d(TAG, "[" + token + "] Phase1; call timed out");
+            } else if (resolutionStatus != RESOLUTION_SUCCESS) {
+                Log.d(TAG, "[" + token + "] Phase1; service connection error");
+            } else {
+                Log.d(TAG, "[" + token + "] Phase1; No results matched");
+            }
         }
         return resolveInfo;
     }
@@ -111,7 +143,7 @@
         final long startTime = System.currentTimeMillis();
         final String token = requestObj.responseObj.token;
         if (DEBUG_EPHEMERAL) {
-            Log.d(TAG, "[" + token + "] Resolving phase 2");
+            Log.d(TAG, "[" + token + "] Phase2; resolving");
         }
         final Intent intent = requestObj.origIntent;
         final String hostName = intent.getData().getHost();
@@ -170,8 +202,24 @@
                 context.startActivity(installerIntent);
             }
         };
-        connection.getInstantAppIntentFilterList(
-                shaPrefix, token, hostName, callback, callbackHandler, startTime);
+        try {
+            connection.getInstantAppIntentFilterList(
+                    shaPrefix, token, hostName, callback, callbackHandler, startTime);
+        } catch (ConnectionException e) {
+            @ResolutionStatus int resolutionStatus = RESOLUTION_FAILURE;
+            if (e.failure == ConnectionException.FAILURE_BIND) {
+                resolutionStatus = RESOLUTION_BIND_TIMEOUT;
+            }
+            logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO, startTime, token,
+                    resolutionStatus);
+            if (DEBUG_EPHEMERAL) {
+                if (resolutionStatus == RESOLUTION_BIND_TIMEOUT) {
+                    Log.d(TAG, "[" + token + "] Phase2; bind timed out");
+                } else {
+                    Log.d(TAG, "[" + token + "] Phase2; service connection error");
+                }
+            }
+        }
     }
 
     /**
@@ -322,7 +370,8 @@
         return null;
     }
 
-    private static void logMetrics(int action, long startTime, String token, int status) {
+    private static void logMetrics(int action, long startTime, String token,
+            @ResolutionStatus int status) {
         final LogMaker logMaker = new LogMaker(action)
                 .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
                 .addTaggedData(FIELD_INSTANT_APP_RESOLUTION_DELAY_MS,
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 2e4b49a..271045a 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -316,6 +316,7 @@
 
                 if (arg == null) {
                     builder.append('!');
+                    return;
                 }
 
                 String txt = String.valueOf(arg);
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 8ca7b96..5ea6362 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -47,7 +47,6 @@
 import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
 import static com.android.server.pm.Installer.DEXOPT_PROFILE_GUIDED;
 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
-import static com.android.server.pm.Installer.DEXOPT_SAFEMODE;
 import static com.android.server.pm.Installer.DEXOPT_SECONDARY_DEX;
 import static com.android.server.pm.Installer.DEXOPT_FORCE;
 import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
@@ -404,7 +403,6 @@
 
     private int getDexFlags(ApplicationInfo info, String compilerFilter) {
         int flags = info.flags;
-        boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
         boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
         // Profile guide compiled oat files should not be public.
         boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter);
@@ -412,7 +410,6 @@
         int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
         int dexFlags =
                 (isPublic ? DEXOPT_PUBLIC : 0)
-                | (vmSafeMode ? DEXOPT_SAFEMODE : 0)
                 | (debuggable ? DEXOPT_DEBUGGABLE : 0)
                 | profileFlag
                 | DEXOPT_BOOTCOMPLETE;
@@ -594,9 +591,6 @@
         if ((flags & DEXOPT_PUBLIC) == DEXOPT_PUBLIC) {
             flagsList.add("public");
         }
-        if ((flags & DEXOPT_SAFEMODE) == DEXOPT_SAFEMODE) {
-            flagsList.add("safemode");
-        }
         if ((flags & DEXOPT_SECONDARY_DEX) == DEXOPT_SECONDARY_DEX) {
             flagsList.add("secondary");
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3a0f9df..1bb8427 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4220,7 +4220,6 @@
             final boolean allowMatchInstant =
                     (includeInstantApps
                             && Intent.ACTION_VIEW.equals(intent.getAction())
-                            && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
                             && hasWebURI(intent))
                     || isSpecialProcess
                     || mContext.checkCallingOrSelfPermission(
@@ -6500,11 +6499,12 @@
             String resolvedType, int flags, int userId) {
         // first, check to see if we've got an instant app already installed
         final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
-        boolean localInstantAppAvailable = false;
+        ResolveInfo localInstantApp = null;
         boolean blockResolution = false;
         if (!alreadyResolvedLocally) {
             final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
                     flags
+                        | PackageManager.GET_RESOLVED_FILTER
                         | PackageManager.MATCH_INSTANT
                         | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
                     userId);
@@ -6531,7 +6531,7 @@
                         if (DEBUG_EPHEMERAL) {
                             Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
                         }
-                        localInstantAppAvailable = true;
+                        localInstantApp = info;
                         break;
                     }
                 }
@@ -6539,17 +6539,29 @@
         }
         // no app installed, let's see if one's available
         AuxiliaryResolveInfo auxiliaryResponse = null;
-        if (!localInstantAppAvailable && !blockResolution) {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
-            final InstantAppRequest requestObject = new InstantAppRequest(
-                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
-                    null /*callingPackage*/, userId, null /*verificationBundle*/);
-            auxiliaryResponse =
-                    InstantAppResolver.doInstantAppResolutionPhaseOne(
-                            mContext, mInstantAppResolverConnection, requestObject);
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        if (!blockResolution) {
+            if (localInstantApp == null) {
+                // we don't have an instant app locally, resolve externally
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
+                final InstantAppRequest requestObject = new InstantAppRequest(
+                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
+                        null /*callingPackage*/, userId, null /*verificationBundle*/);
+                auxiliaryResponse =
+                        InstantAppResolver.doInstantAppResolutionPhaseOne(
+                                mContext, mInstantAppResolverConnection, requestObject);
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            } else {
+                // we have an instant application locally, but, we can't admit that since
+                // callers shouldn't be able to determine prior browsing. create a dummy
+                // auxiliary response so the downstream code behaves as if there's an
+                // instant application available externally. when it comes time to start
+                // the instant application, we'll do the right thing.
+                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
+                auxiliaryResponse = new AuxiliaryResolveInfo(
+                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
+            }
         }
-        if (localInstantAppAvailable || auxiliaryResponse != null) {
+        if (auxiliaryResponse != null) {
             if (DEBUG_EPHEMERAL) {
                 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
             }
@@ -6569,7 +6581,7 @@
                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
                 ephemeralInstaller.filter.addDataPath(
                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
-                ephemeralInstaller.instantAppAvailable = true;
+                ephemeralInstaller.isInstantAppAvailable = true;
                 result.add(ephemeralInstaller);
             }
         }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index bed8f1a..7f0528a 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1611,6 +1611,11 @@
      */
     private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate,
             boolean forPinRequest) {
+        if (shortcut.isReturnedByServer()) {
+            Log.w(TAG,
+                    "Re-publishing ShortcutInfo returned by server is not supported."
+                    + " Some information such as icon may lost from shortcut.");
+        }
         Preconditions.checkNotNull(shortcut, "Null shortcut detected");
         if (shortcut.getActivity() != null) {
             Preconditions.checkState(
@@ -1670,6 +1675,13 @@
         }
     }
 
+    private List<ShortcutInfo> setReturnedByServer(List<ShortcutInfo> shortcuts) {
+        for (int i = shortcuts.size() - 1; i >= 0; i--) {
+            shortcuts.get(i).setReturnedByServer();
+        }
+        return shortcuts;
+    }
+
     // === APIs ===
 
     @Override
@@ -2049,7 +2061,7 @@
         final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
         ps.findAll(ret, query, cloneFlags);
 
-        return new ParceledListSlice<>(ret);
+        return new ParceledListSlice<>(setReturnedByServer(ret));
     }
 
     @Override
@@ -2406,7 +2418,7 @@
                     });
                 }
             }
-            return ret;
+            return setReturnedByServer(ret);
         }
 
         private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 6120ff4..857025d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5485,7 +5485,8 @@
                 // Maintain fullscreen layout until incoming animation is complete.
                 topIsFullscreen = mTopIsFullscreen && mStatusBar.isAnimatingLw();
                 // Transient status bar on the lockscreen is not allowed
-                if (mForceStatusBarFromKeyguard && mStatusBarController.isTransientShowing()) {
+                if ((mForceStatusBarFromKeyguard || statusBarExpanded)
+                        && mStatusBarController.isTransientShowing()) {
                     mStatusBarController.updateVisibilityLw(false /*transientAllowed*/,
                             mLastSystemUiFlags, mLastSystemUiFlags);
                 }
diff --git a/services/core/java/com/android/server/radio/Tuner.java b/services/core/java/com/android/server/radio/Tuner.java
index 0f40883..5d87aa5 100644
--- a/services/core/java/com/android/server/radio/Tuner.java
+++ b/services/core/java/com/android/server/radio/Tuner.java
@@ -36,10 +36,10 @@
     private int mRegion;  // TODO(b/36863239): find better solution to manage regions
     private final boolean mWithAudio;
 
-    Tuner(@NonNull ITunerCallback clientCallback, int region, boolean withAudio) {
+    Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio) {
         mRegion = region;
         mWithAudio = withAudio;
-        mNativeContext = nativeInit(clientCallback);
+        mNativeContext = nativeInit(clientCallback, halRev);
     }
 
     @Override
@@ -48,7 +48,7 @@
         super.finalize();
     }
 
-    private native long nativeInit(@NonNull ITunerCallback clientCallback);
+    private native long nativeInit(@NonNull ITunerCallback clientCallback, int halRev);
     private native void nativeFinalize(long nativeContext);
     private native void nativeClose(long nativeContext);
 
@@ -56,6 +56,13 @@
             @NonNull RadioManager.BandConfig config);
     private native RadioManager.BandConfig nativeGetConfiguration(long nativeContext, int region);
 
+    private native void nativeStep(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeScan(long nativeContext, boolean directionDown, boolean skipSubChannel);
+    private native void nativeTune(long nativeContext, int channel, int subChannel);
+    private native void nativeCancel(long nativeContext);
+
+    private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
+
     @Override
     public void close() {
         synchronized (mLock) {
@@ -82,15 +89,6 @@
     }
 
     @Override
-    public int getProgramInformation(RadioManager.ProgramInfo[] infoOut) {
-        if (infoOut == null || infoOut.length != 1) {
-            throw new IllegalArgumentException("The argument must be an array of length 1");
-        }
-        Slog.d(TAG, "getProgramInformation()");
-        return RadioManager.STATUS_INVALID_OPERATION;
-    }
-
-    @Override
     public void setMuted(boolean mute) {
         if (!mWithAudio) {
             throw new IllegalStateException("Can't operate on mute - no audio requested");
@@ -114,4 +112,39 @@
             return mIsMuted;
         }
     }
+
+    @Override
+    public void step(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            nativeStep(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void scan(boolean directionDown, boolean skipSubChannel) {
+        synchronized (mLock) {
+            nativeScan(mNativeContext, directionDown, skipSubChannel);
+        }
+    }
+
+    @Override
+    public void tune(int channel, int subChannel) {
+        synchronized (mLock) {
+            nativeTune(mNativeContext, channel, subChannel);
+        }
+    }
+
+    @Override
+    public void cancel() {
+        synchronized (mLock) {
+            nativeCancel(mNativeContext);
+        }
+    }
+
+    @Override
+    public RadioManager.ProgramInfo getProgramInformation() {
+        synchronized (mLock) {
+            return nativeGetProgramInformation(mNativeContext);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
index 4035ade..9a08ac3 100644
--- a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
+++ b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
@@ -73,13 +73,13 @@
         final int userId = UserHandle.myUserId();
         UserEnvironment environment = new UserEnvironment(userId);
         LogRunnable task = new LogRunnable();
-        task.setRootDirectory(environment.getExternalStorageDirectory());
         task.setDownloadsDirectory(
                 environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
         task.setSystemSize(FileCollector.getSystemSize(this));
         task.setLogOutputFile(new File(DUMPSYS_CACHE_PATH));
         task.setAppCollector(collector);
         task.setJobService(this, params);
+        task.setContext(this);
         AsyncTask.execute(task);
         return true;
     }
@@ -106,7 +106,8 @@
     }
 
     private static boolean isCharging(Context context) {
-        BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
+        BatteryManager batteryManager =
+                (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
         if (batteryManager != null) {
             return batteryManager.isCharging();
         }
@@ -127,14 +128,10 @@
         private JobParameters mParams;
         private AppCollector mCollector;
         private File mOutputFile;
-        private File mRootDirectory;
         private File mDownloadsDirectory;
+        private Context mContext;
         private long mSystemSize;
 
-        public void setRootDirectory(File file) {
-            mRootDirectory = file;
-        }
-
         public void setDownloadsDirectory(File file) {
             mDownloadsDirectory = file;
         }
@@ -151,14 +148,25 @@
             mSystemSize = size;
         }
 
+        public void setContext(Context context) {
+            mContext = context;
+        }
+
         public void setJobService(JobService jobService, JobParameters params) {
             mJobService = jobService;
             mParams = params;
         }
 
         public void run() {
-            FileCollector.MeasurementResult mainCategories =
-                    FileCollector.getMeasurementResult(mRootDirectory);
+            FileCollector.MeasurementResult mainCategories;
+            try {
+                mainCategories = FileCollector.getMeasurementResult(mContext);
+            } catch (IllegalStateException e) {
+                // This can occur if installd has an issue.
+                Log.e(TAG, "Error while measuring storage", e);
+                finishJob(true);
+                return;
+            }
             FileCollector.MeasurementResult downloads =
                     FileCollector.getMeasurementResult(mDownloadsDirectory);
 
@@ -168,12 +176,10 @@
                 needsReschedule = false;
                 logToFile(mainCategories, downloads, stats, mSystemSize);
             } else {
-                Log.w("TAG", "Timed out while fetching package stats.");
+                Log.w(TAG, "Timed out while fetching package stats.");
             }
 
-            if (mJobService != null) {
-                mJobService.jobFinished(mParams, needsReschedule);
-            }
+            finishJob(needsReschedule);
         }
 
         private void logToFile(MeasurementResult mainCategories, MeasurementResult downloads,
@@ -187,5 +193,11 @@
                 Log.e(TAG, "Exception while writing opportunistic disk file cache.", e);
             }
         }
+
+        private void finishJob(boolean needsReschedule) {
+            if (mJobService != null) {
+                mJobService.jobFinished(mParams, needsReschedule);
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/storage/FileCollector.java b/services/core/java/com/android/server/storage/FileCollector.java
index 90f9f139..0c119a7 100644
--- a/services/core/java/com/android/server/storage/FileCollector.java
+++ b/services/core/java/com/android/server/storage/FileCollector.java
@@ -17,13 +17,17 @@
 package com.android.server.storage;
 
 import android.annotation.IntDef;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.util.ArrayMap;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Map;
@@ -154,15 +158,46 @@
     }
 
     /**
+     * Returns the file categorization result for the primary internal storage UUID.
+     *
+     * @param context
+     */
+    public static MeasurementResult getMeasurementResult(Context context) {
+        MeasurementResult result = new MeasurementResult();
+        StorageStatsManager ssm =
+                (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
+        ExternalStorageStats stats = null;
+        try {
+            stats =
+                    ssm.queryExternalStatsForUser(
+                            StorageManager.UUID_PRIVATE_INTERNAL,
+                            UserHandle.of(context.getUserId()));
+            result.imagesSize = stats.getImageBytes();
+            result.videosSize = stats.getVideoBytes();
+            result.audioSize = stats.getAudioBytes();
+            result.miscSize =
+                    stats.getTotalBytes()
+                            - result.imagesSize
+                            - result.videosSize
+                            - result.audioSize;
+        } catch (IOException e) {
+            throw new IllegalStateException("Could not query storage");
+        }
+
+        return result;
+    }
+
+    /**
      * Returns the size of a system for a given context. This is done by finding the difference
      * between the shared data and the total primary storage size.
+     *
      * @param context Context to use to get storage information.
      */
     public static long getSystemSize(Context context) {
         PackageManager pm = context.getPackageManager();
         VolumeInfo primaryVolume = pm.getPrimaryStorageCurrentVolume();
 
-        StorageManager sm = context.getSystemService(StorageManager.class);
+        StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
         VolumeInfo shared = sm.findEmulatedForPrivate(primaryVolume);
         if (shared == null) {
             return 0;
diff --git a/services/core/java/com/android/server/text/TextClassificationService.java b/services/core/java/com/android/server/text/TextClassificationService.java
deleted file mode 100644
index 9358238..0000000
--- a/services/core/java/com/android/server/text/TextClassificationService.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.text;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.text.ITextClassificationService;
-import android.util.Slog;
-
-import com.android.server.SystemService;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-/**
- * Text classification service.
- * This is used to provide access to the text classification LSTM model file.
- */
-public class TextClassificationService extends ITextClassificationService.Stub {
-
-    private static final String LOG_TAG = "TextClassificationService";
-
-    public static final class Lifecycle extends SystemService {
-
-        private TextClassificationService mService;
-
-        public Lifecycle(Context context) {
-            super(context);
-            mService = new TextClassificationService();
-        }
-
-        @Override
-        public void onStart() {
-            try {
-                publishBinderService(Context.TEXT_CLASSIFICATION_SERVICE, mService);
-            } catch (Throwable t) {
-                // Starting this service is not critical to the running of this device and should
-                // therefore not crash the device. If it fails, log the error and continue.
-                Slog.e(LOG_TAG, "Could not start the TextClassificationService.", t);
-            }
-        }
-    }
-
-    @Override
-    public synchronized ParcelFileDescriptor getModelFileFd() throws RemoteException {
-        try {
-            return ParcelFileDescriptor.open(
-                    new File("/etc/assistant/smart-selection.model"),
-                    ParcelFileDescriptor.MODE_READ_ONLY);
-        } catch (Throwable t) {
-            Slog.e(LOG_TAG, "Error retrieving an fd to the text classification model file.", t);
-            throw new RemoteException(t.getMessage());
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index c6393e78..5bd485c 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -106,6 +106,7 @@
     private static final int MSG_UNLOCK_USER = 11;
     private static final int MSG_STOP_USER = 12;
     private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
+    private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
 
     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
 
@@ -125,9 +126,13 @@
     @GuardedBy("mDeviceLockedForUser")
     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
 
-    @GuardedBy("mDeviceLockedForUser")
+    @GuardedBy("mTrustUsuallyManagedForUser")
     private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
 
+    // set to true only if user can skip bouncer
+    @GuardedBy("mUsersUnlockedByFingerprint")
+    private SparseBooleanArray mUsersUnlockedByFingerprint = new SparseBooleanArray();
+
     private final StrongAuthTracker mStrongAuthTracker;
 
     private boolean mTrustAgentsCanRun = false;
@@ -409,7 +414,6 @@
                     + " must be USER_ALL or a specific user.", new Throwable("here"));
             userId = UserHandle.USER_ALL;
         }
-
         List<UserInfo> userInfos;
         if (userId == UserHandle.USER_ALL) {
             userInfos = mUserManager.getUsers(true /* excludeDying */);
@@ -432,13 +436,19 @@
             boolean secure = mLockPatternUtils.isSecure(id);
             boolean trusted = aggregateIsTrusted(id);
             boolean showingKeyguard = true;
+            boolean fingerprintAuthenticated = false;
+
             if (mCurrentUser == id) {
+                synchronized(mUsersUnlockedByFingerprint) {
+                    fingerprintAuthenticated = mUsersUnlockedByFingerprint.get(id, false);
+                }
                 try {
                     showingKeyguard = wm.isKeyguardLocked();
                 } catch (RemoteException e) {
                 }
             }
-            boolean deviceLocked = secure && showingKeyguard && !trusted;
+            boolean deviceLocked = secure && showingKeyguard && !trusted &&
+                    !fingerprintAuthenticated;
             setDeviceLockedForUser(id, deviceLocked);
         }
     }
@@ -986,6 +996,26 @@
                     "query trust state");
             return isTrustUsuallyManagedInternal(userId);
         }
+
+        @Override
+        public void unlockedByFingerprintForUser(int userId) {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.put(userId, true);
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
+                    0 /* arg2 */).sendToTarget();
+        }
+
+        @Override
+        public void clearAllFingerprints() {
+            enforceReportPermission();
+            synchronized(mUsersUnlockedByFingerprint) {
+                mUsersUnlockedByFingerprint.clear();
+            }
+            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
+                    0 /* arg2 */).sendToTarget();
+        }
     };
 
     private boolean isTrustUsuallyManagedInternal(int userId) {
@@ -1073,6 +1103,9 @@
                         }
                     }
                     break;
+                case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
+                    refreshDeviceLockedForUser(msg.arg1);
+                    break;
             }
         }
     };
@@ -1132,6 +1165,9 @@
                     synchronized (mTrustUsuallyManagedForUser) {
                         mTrustUsuallyManagedForUser.delete(userId);
                     }
+                    synchronized (mUsersUnlockedByFingerprint) {
+                        mUsersUnlockedByFingerprint.delete(userId);
+                    }
                     refreshAgentList(userId);
                     refreshDeviceLockedForUser(userId);
                 }
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 0e183f0..9ef7410 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -39,7 +39,6 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -47,7 +46,6 @@
 import android.service.vr.IVrListener;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
-import android.service.vr.IVrWindowManager;
 import android.service.vr.VrListenerService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -440,18 +438,6 @@
         }
 
         @Override
-        public void connectController(FileDescriptor fd) throws android.os.RemoteException {
-            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
-            VrManagerService.this.connectController(fd);
-        }
-
-        @Override
-        public void disconnectController() throws android.os.RemoteException {
-            enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
-            VrManagerService.this.disconnectController();
-        }
-
-        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
@@ -1184,20 +1170,4 @@
             return mVrModeEnabled;
         }
     }
-
-    private void connectController(FileDescriptor fd) throws android.os.RemoteException {
-        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
-        IVrWindowManager remote =
-                IVrWindowManager.Stub.asInterface(
-                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
-        remote.connectController(fd);
-    }
-
-    private void disconnectController() throws android.os.RemoteException {
-        // TODO(b/36506799): move vr_wm code to VrCore and remove this.
-        IVrWindowManager remote =
-                IVrWindowManager.Stub.asInterface(
-                        ServiceManager.getService(IVrWindowManager.SERVICE_NAME));
-        remote.disconnectController();
-    }
 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7b31cf6..70782dd 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -52,9 +52,11 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -165,6 +167,7 @@
     static final String WALLPAPER_LOCK_ORIG = "wallpaper_lock_orig";
     static final String WALLPAPER_LOCK_CROP = "wallpaper_lock";
     static final String WALLPAPER_INFO = "wallpaper_info.xml";
+    static final int MAX_WALLPAPER_EXTRACTION_AREA = 112 * 112;
 
     // All the various per-user state files we need to be aware of
     static final String[] sPerUserFiles = new String[] {
@@ -376,43 +379,89 @@
         }
     }
 
+    /**
+     * We can easily extract colors from an ImageWallpaper since it's only a bitmap.
+     * In this case, using the crop is more than enough.
+     *
+     * In case of a live wallpaper, the best we can do is to extract colors from its
+     * preview image. Anyway, the live wallpaper can also implement the wallpaper colors API
+     * to report when colors change.
+     *
+     * @param wallpaper a wallpaper representation
+     */
     private void extractColors(WallpaperData wallpaper) {
         String cropFile = null;
+        Drawable thumbnail = null;
+        // This represents a maximum pixel count in an image.
+        // It prevents color extraction on big bitmaps.
         int wallpaperId = -1;
-        synchronized (mLock) {
-            // Only extract colors of ImageWallpaper or lock wallpapers (null)
-            final boolean supportedComponent = mImageWallpaper.equals(wallpaper.wallpaperComponent)
-                    || wallpaper.wallpaperComponent == null;
-            if (!supportedComponent)
-                return;
 
-            if (wallpaper.cropFile != null && wallpaper.cropFile.exists()) {
-                cropFile = wallpaper.cropFile.getAbsolutePath();
+        synchronized (mLock) {
+            final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
+                    || wallpaper.wallpaperComponent == null;
+            if (imageWallpaper) {
+                if (wallpaper.cropFile != null && wallpaper.cropFile.exists()) {
+                    cropFile = wallpaper.cropFile.getAbsolutePath();
+                }
+            } else {
+                if (wallpaper.connection == null) {
+                    Slog.w(TAG, "Can't extract colors, wallpaper not connected. " +
+                            wallpaper.wallpaperId);
+                    return;
+                }
+                WallpaperInfo info = wallpaper.connection.mInfo;
+                if (info == null) {
+                    Slog.w(TAG, "Something is really wrong, live wallpaper doesn't have " +
+                           "a WallpaperInfo object! " + wallpaper.wallpaperId);
+                    return;
+                }
+                thumbnail = info.loadThumbnail(mContext.getPackageManager());
             }
+
             wallpaperId = wallpaper.wallpaperId;
         }
 
+        Bitmap bitmap = null;
         if (cropFile != null) {
-            final Bitmap bitmap = BitmapFactory.decodeFile(cropFile);
-            if (bitmap == null) {
-                Slog.w(TAG, "Cannot extract colors because wallpaper file could not be read.");
-                return;
+            bitmap = BitmapFactory.decodeFile(cropFile);
+        } else if (thumbnail != null) {
+            // Calculate how big the bitmap needs to be.
+            // This avoids unnecessary processing and allocation inside Palette.
+            final int requestedArea = thumbnail.getIntrinsicWidth() *
+                    thumbnail.getIntrinsicHeight();
+            double scale = 1;
+            if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+                scale = Math.sqrt(MAX_WALLPAPER_EXTRACTION_AREA / (double) requestedArea);
             }
-            Palette palette = Palette.from(bitmap).generate();
-            bitmap.recycle();
+            bitmap = Bitmap.createBitmap((int) (thumbnail.getIntrinsicWidth() * scale),
+                    (int) (thumbnail.getIntrinsicHeight() * scale), Bitmap.Config.ARGB_8888);
+            final Canvas bmpCanvas = new Canvas(bitmap);
+            thumbnail.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+            thumbnail.draw(bmpCanvas);
+        }
 
-            final List<Pair<Color, Integer>> colors = new ArrayList<>();
-            for (Palette.Swatch swatch : palette.getSwatches()) {
-                colors.add(new Pair<>(Color.valueOf(swatch.getRgb()),
-                        swatch.getPopulation()));
-            }
+        if (bitmap == null) {
+            Slog.w(TAG, "Cannot extract colors because wallpaper could not be read.");
+            return;
+        }
 
-            synchronized (mLock) {
-                if (wallpaper.wallpaperId == wallpaperId) {
-                    wallpaper.primaryColors = new WallpaperColors(colors);
-                } else {
-                    Slog.w(TAG, "Not setting primary colors since wallpaper changed");
-                }
+        Palette palette = Palette
+                .from(bitmap)
+                .resizeBitmapArea(MAX_WALLPAPER_EXTRACTION_AREA)
+                .generate();
+        bitmap.recycle();
+
+        final List<Pair<Color, Integer>> colors = new ArrayList<>();
+        for (Palette.Swatch swatch : palette.getSwatches()) {
+            colors.add(new Pair<>(Color.valueOf(swatch.getRgb()),
+                    swatch.getPopulation()));
+        }
+
+        synchronized (mLock) {
+            if (wallpaper.wallpaperId == wallpaperId) {
+                wallpaper.primaryColors = new WallpaperColors(colors);
+            } else {
+                Slog.w(TAG, "Not setting primary colors since wallpaper changed");
             }
         }
     }
@@ -817,6 +866,11 @@
          */
         @Override
         public void onWallpaperColorsChanged(WallpaperColors primaryColors) {
+            // Do not override default color extraction if API isn't implemented.
+            if (primaryColors == null) {
+                return;
+            }
+
             int which;
             synchronized (mLock) {
                 // Do not broadcast changes on ImageWallpaper since it's handled
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 7a36da2..a38addb 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -54,6 +54,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.os.Binder;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
@@ -1808,27 +1809,25 @@
             final IAppTransitionAnimationSpecsFuture future
                     = mNextAppTransitionAnimationsSpecsFuture;
             mNextAppTransitionAnimationsSpecsFuture = null;
-            mDefaultExecutor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    AppTransitionAnimationSpec[] specs = null;
-                    try {
-                        specs = future.get();
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "Failed to fetch app transition specs: " + e);
-                    }
-                    synchronized (mService.mWindowMap) {
-                        mNextAppTransitionAnimationsSpecsPending = false;
-                        overridePendingAppTransitionMultiThumb(specs,
-                                mNextAppTransitionFutureCallback, null /* finishedCallback */,
-                                mNextAppTransitionScaleUp);
-                        mNextAppTransitionFutureCallback = null;
-                        if (specs != null) {
-                            mService.prolongAnimationsFromSpecs(specs, mNextAppTransitionScaleUp);
-                        }
-                    }
-                    mService.requestTraversal();
+            mDefaultExecutor.execute(() -> {
+                AppTransitionAnimationSpec[] specs = null;
+                try {
+                    Binder.allowBlocking(future.asBinder());
+                    specs = future.get();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to fetch app transition specs: " + e);
                 }
+                synchronized (mService.mWindowMap) {
+                    mNextAppTransitionAnimationsSpecsPending = false;
+                    overridePendingAppTransitionMultiThumb(specs,
+                            mNextAppTransitionFutureCallback, null /* finishedCallback */,
+                            mNextAppTransitionScaleUp);
+                    mNextAppTransitionFutureCallback = null;
+                    if (specs != null) {
+                        mService.prolongAnimationsFromSpecs(specs, mNextAppTransitionScaleUp);
+                    }
+                }
+                mService.requestTraversal();
             });
         }
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 640bac2..982561c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -53,6 +53,7 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.SystemClock;
@@ -70,6 +71,8 @@
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 
+import static android.os.Build.VERSION_CODES.O;
+
 class AppTokenList extends ArrayList<AppWindowToken> {
 }
 
@@ -1245,7 +1248,11 @@
      */
     @Override
     int getOrientation(int candidate) {
-        if (!fillsParent()) {
+        // We do not allow non-fullscreen apps to influence orientation at and beyond O. While we do
+        // throw an exception in {@link Activity#onCreate} and
+        // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that
+        // other calculations aren't affected.
+        if (!fillsParent() && mTargetSdk >= O) {
             // Can't specify orientation if app doesn't fill parent.
             return SCREEN_ORIENTATION_UNSET;
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 92d26cb..257f285 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -759,16 +759,25 @@
         return token.asAppWindowToken();
     }
 
-    void addWindowToken(IBinder binder, WindowToken token) {
+    private void addWindowToken(IBinder binder, WindowToken token) {
         final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
         if (dc != null) {
             // We currently don't support adding a window token to the display if the display
             // already has the binder mapped to another token. If there is a use case for supporting
             // this moving forward we will either need to merge the WindowTokens some how or have
             // the binder map to a list of window tokens.
-            throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
-                    + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
+            throw new IllegalArgumentException("Can't map token=" + token + " to display="
+                    + getName() + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
         }
+        if (binder == null) {
+            throw new IllegalArgumentException("Can't map token=" + token + " to display="
+                    + getName() + " binder is null");
+        }
+        if (token == null) {
+            throw new IllegalArgumentException("Can't map null token to display="
+                    + getName() + " binder=" + binder);
+        }
+
         mTokenMap.put(binder, token);
 
         if (token.asAppWindowToken() == null) {
@@ -1503,16 +1512,8 @@
         return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
     }
 
-    /**
-     * Returns the orientation that this display should be in factoring in its children containers.
-     *
-     * @param includeAppContainers True if then app containers (stacks, tasks, ...) should be
-     *                             factored in when determining the orientation. If false only
-     *                             non-app/system containers will be used to determine the returned
-     *                             orientation.
-     * @return The orientation the display should be in.
-     */
-    int getOrientation(boolean includeAppContainers) {
+    @Override
+    int getOrientation() {
         final WindowManagerPolicy policy = mService.mPolicy;
 
         if (mService.mDisplayFrozen) {
@@ -1541,14 +1542,8 @@
             }
         }
 
-        // Top system windows are not requesting an orientation. Get orientation from app containers
-        // if allowed. Otherwise, return the last orientation.
-        return includeAppContainers ? mTaskStackContainers.getOrientation() : mLastOrientation;
-    }
-
-    @Override
-    int getOrientation() {
-        return getOrientation(true /* includeAppContainers */);
+        // Top system windows are not requesting an orientation. Start searching from apps.
+        return mTaskStackContainers.getOrientation();
     }
 
     void updateDisplayInfo() {
@@ -2499,7 +2494,8 @@
     void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
         final WindowManagerPolicy policy = mService.mPolicy;
         forAllWindows(w -> {
-            if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)) {
+            if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)
+                    && w.wouldBeVisibleIfPolicyIgnored() && !w.isVisible()) {
                 w.mWinAnimator.setAnimation(
                         policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
             }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a48397b..63cc9bf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1239,7 +1239,8 @@
                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                     }
                 }
-                token = new WindowToken(this, attrs.token, type, false, displayContent,
+                final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
+                token = new WindowToken(this, binder, type, false, displayContent,
                         session.mCanAddInternalSystemWindow);
             } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                 atoken = token.asAppWindowToken();
@@ -1310,7 +1311,7 @@
                 // It is not valid to use an app token with other system types; we will
                 // instead make a new token for it (as if null had been passed in for the token).
                 attrs.token = null;
-                token = new WindowToken(this, null, type, false, displayContent,
+                token = new WindowToken(this, client.asBinder(), type, false, displayContent,
                         session.mCanAddInternalSystemWindow);
             }
 
@@ -2373,7 +2374,7 @@
         try {
             synchronized(mWindowMap) {
                 config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
-                        displayId, true /* includeAppContainers */);
+                        displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -2383,13 +2384,13 @@
     }
 
     private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
-            IBinder freezeThisOneIfNeeded, int displayId, boolean includeAppContainers) {
+            IBinder freezeThisOneIfNeeded, int displayId) {
         if (!mDisplayReady) {
             return null;
         }
         Configuration config = null;
 
-        if (updateOrientationFromAppTokensLocked(false, displayId, includeAppContainers)) {
+        if (updateOrientationFromAppTokensLocked(false, displayId)) {
             // If we changed the orientation but mOrientationChangeComplete is already true,
             // we used seamless rotation, and we don't need to freeze the screen.
             if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
@@ -2427,11 +2428,6 @@
         return config;
     }
 
-    boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
-        return updateOrientationFromAppTokensLocked(inTransaction, displayId,
-                false /* includeAppContainers */);
-    }
-
     /**
      * Determine the new desired orientation of the display, returning a non-null new Configuration
      * if it has changed from the current orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
@@ -2442,25 +2438,13 @@
      * The orientation is computed from non-application windows first. If none of the
      * non-application windows specify orientation, the orientation is computed from application
      * tokens.
-     *
-     * @param inTransaction True if we are currently in a surface transaction.
-     * @param displayId Id of the display to update orientation for.
-     * @param includeAppContainers True if then app containers (stacks, tasks, ...) should be
-     *                             factored in when determining the orientation. If false only
-     *                             non-app/system containers will be used to determine the returned
-     *                             orientation.
-     *                             NOTE: Only call originating from activity manager are expected to
-     *                             set this to true as it needs to synchronize several app states
-     *                             like visibility with the update of display orientation.
-     * @return True if the display orientation was updated.
      * @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
      */
-    private boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId,
-            boolean includeAppContainers) {
-        final long ident = Binder.clearCallingIdentity();
+    boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
+        long ident = Binder.clearCallingIdentity();
         try {
             final DisplayContent dc = mRoot.getDisplayContent(displayId);
-            final int req = dc.getOrientation(includeAppContainers);
+            final int req = dc.getOrientation();
             if (req != dc.getLastOrientation()) {
                 dc.setLastOrientation(req);
                 //send a message to Policy indicating orientation change to take
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 67516c1..25b6561 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1292,36 +1292,14 @@
 
     @Override
     boolean isVisible() {
-        // TODO: The check for hiddenRequested is commented out below, because the window can still
-        // be visible on screen when the flag is true. We would like the isVisible() method to
-        // return an answer closer to if the window is truly visible (can't be an exact answer
-        // without checking the surface state), so comment out the check for now so we can test to
-        // see what problem it causes.
-        // If it doesn't cause any issues, then we can remove just before we lock down the current
-        // release (O) and also consolidate this method with #isVisibleUnchecked() and possibly
-        // other methods like isVisibleNow().
-        // If it does cause problems, then we can look if there are other ways to solve the problem.
-        // If there isn't then uncomment and document here why it is needed.
-        if (/*(mAppToken == null || !mAppToken.hiddenRequested) && */isVisibleUnchecked()
-            // TODO: The window isn't considered visible when the token is hidden, however
-            // uncommenting the check below breaks the visual transition from an app to the launcher
-            // if the home buttons is pressed. Need to investigate an fix that issue before
-            // uncommenting.
-            /* && !mToken.hidden*/) {
-            // Is this window visible?  It is not visible if there is no surface, or we are in the
-            // process of running an exit animation that will remove the surface, or its app token
-            // has been hidden.
-            return true;
-        }
-        return false;
+        return wouldBeVisibleIfPolicyIgnored() && mPolicyVisibility;
     }
 
     /**
-     * Does the minimal check for visibility. Callers generally want to use one of the public
-     * methods as they perform additional checks on the app token.
-     * TODO: See if there are other places we can use this check below instead of duplicating...
+     * @return True if the window would be visible if we'd ignore policy visibility, false
+     *         otherwise.
      */
-    private boolean isVisibleUnchecked() {
+    boolean wouldBeVisibleIfPolicyIgnored() {
         return mHasSurface && mPolicyVisibility && !isParentWindowHidden()
                 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
     }
@@ -1338,7 +1316,7 @@
     // TODO: Can we consolidate this with #isVisible() or have a more appropriate name for this?
     boolean isWinVisibleLw() {
         return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating)
-                && isVisibleUnchecked();
+                && isVisible();
     }
 
     /**
@@ -1347,7 +1325,7 @@
      */
     boolean isVisibleNow() {
         return (!mToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
-                && isVisibleUnchecked();
+                && isVisible();
     }
 
     /**
@@ -2063,7 +2041,7 @@
             // If app died visible, apply a dim over the window to indicate that it's inactive
             dc.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
         } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0
-                && dc != null && !mAnimatingExit && isVisibleUnchecked()) {
+                && dc != null && !mAnimatingExit && isVisible()) {
             dc.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator);
         }
     }
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index af70612..355c350 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -19,13 +19,13 @@
     $(LOCAL_REL_DIR)/com_android_server_lights_LightsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_ContextHubService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_location_GnssLocationProvider.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_locksettings_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_radio_RadioService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_radio_Tuner.cpp \
     $(LOCAL_REL_DIR)/com_android_server_radio_Tuner_TunerCallback.cpp \
     $(LOCAL_REL_DIR)/com_android_server_radio_convert.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \
-    $(LOCAL_REL_DIR)/com_android_server_SyntheticPasswordManager.cpp \
     $(LOCAL_REL_DIR)/com_android_server_storage_AppFuseBridge.cpp \
     $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \
     $(LOCAL_REL_DIR)/com_android_server_tv_TvUinputBridge.cpp \
diff --git a/services/core/jni/JavaRef.cpp b/services/core/jni/JavaRef.cpp
index 4a9cdd9..ad07afa 100644
--- a/services/core/jni/JavaRef.cpp
+++ b/services/core/jni/JavaRef.cpp
@@ -23,24 +23,8 @@
 
 namespace android {
 
-JavaRef make_javaref(JNIEnv *env, jobject ref) {
-    ALOGV("wrapping %p", ref);
-    ALOGE_IF(env == nullptr, "Environment is a nullptr");
-
-    return JavaRef(ref, [env](jobject ref) {
-        ALOGV("deleting %p", ref);
-        if (env && ref) {
-            env->DeleteLocalRef(ref);
-        }
-    });
-}
-
 EnvWrapper::EnvWrapper(JNIEnv *env) : mEnv(env) {
     ALOGE_IF(env == nullptr, "Environment is a nullptr");
 }
 
-JavaRef EnvWrapper::operator() (jobject ref) const {
-    return make_javaref(mEnv, ref);
-}
-
 } // namespace android
diff --git a/services/core/jni/JavaRef.h b/services/core/jni/JavaRef.h
index c25f289..8a572e2 100644
--- a/services/core/jni/JavaRef.h
+++ b/services/core/jni/JavaRef.h
@@ -21,17 +21,30 @@
 #include <functional>
 #include <jni.h>
 #include <memory>
+#include <type_traits>
 
 namespace android {
 
-typedef std::unique_ptr<_jobject, std::function<void(jobject)>> JavaRef;
+template <typename T>
+using JavaRef = std::unique_ptr<typename std::remove_pointer<T>::type, std::function<void(T)>>;
 
-JavaRef make_javaref(JNIEnv *env, jobject ref);
+template <typename T>
+JavaRef<T> make_javaref(JNIEnv *env, T ref) {
+    return JavaRef<T>(ref, [env](T ref) {
+        if (env && ref) {
+            env->DeleteLocalRef(ref);
+        }
+    });
+}
 
 class EnvWrapper {
 public:
     EnvWrapper(JNIEnv *env);
-    JavaRef operator() (jobject ref) const;
+
+    template <typename T>
+    JavaRef<T> operator() (T ref) const {
+        return make_javaref(mEnv, ref);
+    }
 
 private:
     JNIEnv *mEnv;
diff --git a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
deleted file mode 100644
index a9f7b9f..0000000
--- a/services/core/jni/com_android_server_SyntheticPasswordManager.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SyntheticPasswordManager"
-
-#include "JNIHelp.h"
-#include "jni.h"
-
-#include <android_runtime/Log.h>
-#include <utils/Timers.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/Log.h>
-#include <gatekeeper/password_handle.h>
-
-
-extern "C" {
-#include "crypto_scrypt.h"
-}
-
-namespace android {
-
-static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
-
-    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
-
-    if (data != NULL) {
-        const gatekeeper::password_handle_t *handle =
-                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
-        jlong sid = handle->user_id;
-        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
-        return sid;
-    } else {
-        return 0;
-    }
-}
-
-static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
-    if (!password || !salt) {
-        return NULL;
-    }
-
-    int passwordLen = env->GetArrayLength(password);
-    int saltLen = env->GetArrayLength(salt);
-    jbyteArray ret = env->NewByteArray(outLen);
-
-    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
-    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
-    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
-
-    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
-                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
-                       outLen);
-    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
-    env->ReleaseByteArrayElements(ret, retPtr, 0);
-
-    if (!rc) {
-        return ret;
-    } else {
-        SLOGE("scrypt failed");
-        return NULL;
-    }
-}
-
-static const JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
-    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
-};
-
-int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "com/android/server/SyntheticPasswordManager",
-                                    sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp
index 813dcf5..514e996 100644
--- a/services/core/jni/com_android_server_lights_LightsService.cpp
+++ b/services/core/jni/com_android_server_lights_LightsService.cpp
@@ -29,16 +29,46 @@
 
 namespace android {
 
-using ILight     = ::android::hardware::light::V2_0::ILight;
 using Brightness = ::android::hardware::light::V2_0::Brightness;
 using Flash      = ::android::hardware::light::V2_0::Flash;
-using Type       = ::android::hardware::light::V2_0::Type;
+using ILight     = ::android::hardware::light::V2_0::ILight;
 using LightState = ::android::hardware::light::V2_0::LightState;
 using Status     = ::android::hardware::light::V2_0::Status;
+using Type       = ::android::hardware::light::V2_0::Type;
 template<typename T>
 using Return     = ::android::hardware::Return<T>;
 
-static sp<ILight> gLight;
+class LightHal {
+private:
+    static sp<ILight> sLight;
+    static bool sLightInit;
+
+    LightHal() {}
+
+public:
+    static void disassociate() {
+        sLightInit = false;
+        sLight = nullptr;
+    }
+
+    static sp<ILight> associate() {
+        if ((sLight == nullptr && !sLightInit) ||
+                (sLight != nullptr && !sLight->ping().isOk())) {
+            // will return the hal if it exists the first time.
+            sLight = ILight::getService();
+            sLightInit = true;
+
+            if (sLight == nullptr) {
+                ALOGE("Unable to get ILight interface.");
+            }
+        }
+
+        return sLight;
+    }
+};
+
+sp<ILight> LightHal::sLight = nullptr;
+bool LightHal::sLightInit = false;
 
 static bool validate(jint light, jint flash, jint brightness) {
     bool valid = true;
@@ -103,7 +133,7 @@
         const LightState &state) {
     if (!ret.isOk()) {
         ALOGE("Failed to issue set light command.");
-        gLight = nullptr;
+        LightHal::disassociate();
         return;
     }
 
@@ -137,12 +167,9 @@
         return;
     }
 
-    if (gLight == nullptr || !gLight->ping().isOk()) {
-        gLight = ILight::getService();
-    }
+    sp<ILight> hal = LightHal::associate();
 
-    if (gLight == nullptr) {
-        ALOGE("Unable to get ILight interface.");
+    if (hal == nullptr) {
         return;
     }
 
@@ -152,7 +179,7 @@
 
     {
         ALOGD_IF_SLOW(50, "Excessive delay setting light");
-        Return<Status> ret = gLight->setLight(type, state);
+        Return<Status> ret = hal->setLight(type, state);
         processReturn(ret, type, state);
     }
 }
diff --git a/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
new file mode 100644
index 0000000..248dedb
--- /dev/null
+++ b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SyntheticPasswordManager"
+
+#include "JNIHelp.h"
+#include "jni.h"
+
+#include <android_runtime/Log.h>
+#include <utils/Timers.h>
+#include <utils/misc.h>
+#include <utils/String8.h>
+#include <utils/Log.h>
+#include <gatekeeper/password_handle.h>
+
+
+extern "C" {
+#include "crypto_scrypt.h"
+}
+
+namespace android {
+
+static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
+
+    jbyte* data = (jbyte*)env->GetPrimitiveArrayCritical(handleArray, NULL);
+
+    if (data != NULL) {
+        const gatekeeper::password_handle_t *handle =
+                reinterpret_cast<const gatekeeper::password_handle_t *>(data);
+        jlong sid = handle->user_id;
+        env->ReleasePrimitiveArrayCritical(handleArray, data, JNI_ABORT);
+        return sid;
+    } else {
+        return 0;
+    }
+}
+
+static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
+    if (!password || !salt) {
+        return NULL;
+    }
+
+    int passwordLen = env->GetArrayLength(password);
+    int saltLen = env->GetArrayLength(salt);
+    jbyteArray ret = env->NewByteArray(outLen);
+
+    jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
+    jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
+    jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
+
+    int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
+                       (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
+                       outLen);
+    env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
+    env->ReleaseByteArrayElements(ret, retPtr, 0);
+
+    if (!rc) {
+        return ret;
+    } else {
+        SLOGE("scrypt failed");
+        return NULL;
+    }
+}
+
+static const JNINativeMethod sMethods[] = {
+     /* name, signature, funcPtr */
+    {"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
+    {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
+};
+
+int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/server/locksettings/SyntheticPasswordManager",
+                                    sMethods, NELEM(sMethods));
+}
+
+} /* namespace android */
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 1bdcd7a..c722629 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -57,6 +57,7 @@
 
 static jobject gPowerManagerServiceObj;
 sp<IPower> gPowerHal = nullptr;
+bool gPowerHalExists = true;
 std::mutex gPowerHalMutex;
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
@@ -78,12 +79,13 @@
 // Check validity of current handle to the power HAL service, and call getService() if necessary.
 // The caller must be holding gPowerHalMutex.
 bool getPowerHal() {
-    if (gPowerHal == nullptr) {
+    if (gPowerHalExists && gPowerHal == nullptr) {
         gPowerHal = IPower::getService();
         if (gPowerHal != nullptr) {
             ALOGI("Loaded power HAL service");
         } else {
             ALOGI("Couldn't load power HAL service");
+            gPowerHalExists = false;
         }
     }
     return gPowerHal != nullptr;
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
index 8b53b1b..c424d30 100644
--- a/services/core/jni/com_android_server_radio_RadioService.cpp
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -22,6 +22,7 @@
 #include "com_android_server_radio_Tuner.h"
 #include "com_android_server_radio_convert.h"
 
+#include <android/hardware/broadcastradio/1.1/IBroadcastRadio.h>
 #include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
 #include <core_jni_helpers.h>
 #include <utils/Log.h>
@@ -39,7 +40,6 @@
 namespace V1_1 = hardware::broadcastradio::V1_1;
 
 using V1_0::Class;
-using V1_0::IBroadcastRadio;
 using V1_0::Result;
 
 using V1_0::BandConfig;
@@ -57,7 +57,7 @@
 struct ServiceContext {
     ServiceContext() {}
 
-    sp<IBroadcastRadio> mModule;
+    sp<V1_0::IBroadcastRadio> mModule;
 
 private:
     DISALLOW_COPY_AND_ASSIGN(ServiceContext);
@@ -90,7 +90,7 @@
     delete ctx;
 }
 
-static sp<IBroadcastRadio> getModule(jlong nativeContext) {
+static sp<V1_0::IBroadcastRadio> getModule(jlong nativeContext) {
     ALOGV("getModule()");
     AutoMutex _l(gContextMutex);
     auto& ctx = getNativeContext(nativeContext);
@@ -106,9 +106,10 @@
         return nullptr;
     }
 
-    sp<IBroadcastRadio> module = nullptr;
+    sp<V1_0::IBroadcastRadio> module = nullptr;
     // TODO(b/36863239): not only AM/FM
-    factory->connectModule(Class::AM_FM, [&](Result retval, const sp<IBroadcastRadio>& result) {
+    factory->connectModule(Class::AM_FM, [&](Result retval,
+            const sp<V1_0::IBroadcastRadio>& result) {
         if (retval == Result::OK) {
             module = result;
         }
@@ -133,10 +134,19 @@
         return nullptr;
     }
 
+    HalRevision halRev;
+    if (V1_1::IBroadcastRadio::castFrom(module).withDefault(nullptr) != nullptr) {
+        ALOGI("Opening tuner with broadcast radio HAL 1.1");
+        halRev = HalRevision::V1_1;
+    } else {
+        ALOGI("Opening tuner with broadcast radio HAL 1.0");
+        halRev = HalRevision::V1_0;
+    }
+
     Region region;
     BandConfig bandConfigHal = convert::BandConfigToHal(env, bandConfig, region);
 
-    jobject tuner = env->NewObject(gTunerClass, gTunerCstor, callback, region, withAudio);
+    jobject tuner = env->NewObject(gTunerClass, gTunerCstor, callback, halRev, region, withAudio);
     if (tuner == nullptr) {
         ALOGE("Unable to create new tuner object.");
         return nullptr;
@@ -184,7 +194,7 @@
     auto tunerClass = FindClassOrDie(env, "com/android/server/radio/Tuner");
     gTunerClass = MakeGlobalRefOrDie(env, tunerClass);
     gTunerCstor = GetMethodIDOrDie(env, tunerClass, "<init>",
-            "(Landroid/hardware/radio/ITunerCallback;IZ)V");
+            "(Landroid/hardware/radio/ITunerCallback;IIZ)V");
 
     auto serviceClass = FindClassOrDie(env, "com/android/server/radio/RadioService");
     gServiceClass = MakeGlobalRefOrDie(env, serviceClass);
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
index 96e122d..052823f 100644
--- a/services/core/jni/com_android_server_radio_Tuner.cpp
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -39,7 +39,6 @@
 namespace V1_1 = hardware::broadcastradio::V1_1;
 
 using V1_0::BandConfig;
-using V1_0::ITuner;
 using V1_0::MetaData;
 using V1_0::Result;
 using V1_1::ITunerCallback;
@@ -57,7 +56,9 @@
 struct TunerContext {
     TunerContext() {}
 
-    sp<ITuner> mHalTuner;
+    HalRevision mHalRev;
+    sp<V1_0::ITuner> mHalTuner;
+    sp<V1_1::ITuner> mHalTuner11;
     sp<TunerCallback> mNativeCallback;
 
 private:
@@ -77,12 +78,13 @@
     return getNativeContext(env->GetLongField(obj, gjni.Tuner.nativeContext));
 }
 
-static jlong nativeInit(JNIEnv *env, jobject obj, jobject clientCallback) {
+static jlong nativeInit(JNIEnv *env, jobject obj, jobject clientCallback, jint halRev) {
     ALOGV("nativeInit()");
     AutoMutex _l(gContextMutex);
 
     auto ctx = new TunerContext();
-    ctx->mNativeCallback = new TunerCallback(env, obj, clientCallback);
+    ctx->mHalRev = static_cast<HalRevision>(halRev);
+    ctx->mNativeCallback = new TunerCallback(env, obj, clientCallback, ctx->mHalRev);
 
     static_assert(sizeof(jlong) >= sizeof(ctx), "jlong is smaller than a pointer");
     return reinterpret_cast<jlong>(ctx);
@@ -96,22 +98,33 @@
     delete ctx;
 }
 
-void setHalTuner(JNIEnv *env, jobject obj, sp<ITuner> halTuner) {
+void setHalTuner(JNIEnv *env, jobject obj, sp<V1_0::ITuner> halTuner) {
     ALOGV("setHalTuner(%p)", halTuner.get());
     ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");
 
     AutoMutex _l(gContextMutex);
     auto& ctx = getNativeContext(env, obj);
+
     ctx.mHalTuner = halTuner;
+    ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
+    ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
+            "Provided tuner does not implement 1.1 HAL");
 }
 
-sp<ITuner> getHalTuner(jlong nativeContext) {
+sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
     AutoMutex _l(gContextMutex);
     auto tuner = getNativeContext(nativeContext).mHalTuner;
     LOG_ALWAYS_FATAL_IF(tuner == nullptr, "HAL tuner not set");
     return tuner;
 }
 
+sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
+    AutoMutex _l(gContextMutex);
+    auto tuner = getNativeContext(nativeContext).mHalTuner11;
+    LOG_ALWAYS_FATAL_IF(tuner == nullptr, "HAL tuner not set");
+    return tuner;
+}
+
 sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject obj) {
     AutoMutex _l(gContextMutex);
     auto& ctx = getNativeContext(env, obj);
@@ -127,6 +140,7 @@
     auto& ctx = getNativeContext(nativeContext);
     ALOGI("Closing tuner %p", ctx.mHalTuner.get());
     ctx.mNativeCallback->detach();
+    ctx.mHalTuner11 = nullptr;
     ctx.mHalTuner = nullptr;
     ctx.mNativeCallback = nullptr;
 }
@@ -152,21 +166,87 @@
         halResult = result;
         halConfig = config;
     });
-    if (convert::ThrowIfFailed(env, hidlResult)) {
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) {
         return nullptr;
     }
 
     return convert::BandConfigFromHal(env, halConfig, region).release();
 }
 
+static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeStep()");
+    auto halTuner = getHalTuner(nativeContext);
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->step(dir, skipSubChannel));
+}
+
+static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
+        bool directionDown, bool skipSubChannel) {
+    ALOGV("nativeScan()");
+    auto halTuner = getHalTuner(nativeContext);
+
+    auto dir = convert::DirectionToHal(directionDown);
+    convert::ThrowIfFailed(env, halTuner->scan(dir, skipSubChannel));
+}
+
+static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext,
+        jint channel, jint subChannel) {
+    ALOGV("nativeTune(%d, %d)", channel, subChannel);
+    auto halTuner = getHalTuner(nativeContext);
+
+    convert::ThrowIfFailed(env, halTuner->tune(channel, subChannel));
+}
+
+static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeCancel()");
+    auto halTuner = getHalTuner(nativeContext);
+
+    convert::ThrowIfFailed(env, halTuner->cancel());
+}
+
+static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
+    ALOGV("nativeGetProgramInformation()");
+    auto halTuner10 = getHalTuner(nativeContext);
+    auto halTuner11 = getHalTuner11(nativeContext);
+
+    V1_1::ProgramInfo halInfo;
+    Result halResult;
+    Return<void> hidlResult;
+    if (halTuner11 != nullptr) {
+        hidlResult = halTuner11->getProgramInformation_1_1([&](Result result,
+                const V1_1::ProgramInfo& info) {
+            halResult = result;
+            halInfo = info;
+        });
+    } else {
+        hidlResult = halTuner10->getProgramInformation([&](Result result,
+                const V1_0::ProgramInfo& info) {
+            halResult = result;
+            halInfo.base = info;
+        });
+    }
+
+    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return nullptr;
+
+    return convert::ProgramInfoFromHal(env, halInfo).release();
+}
+
 static const JNINativeMethod gTunerMethods[] = {
-    { "nativeInit", "(Landroid/hardware/radio/ITunerCallback;)J", (void*)nativeInit },
+    { "nativeInit", "(Landroid/hardware/radio/ITunerCallback;I)J", (void*)nativeInit },
     { "nativeFinalize", "(J)V", (void*)nativeFinalize },
     { "nativeClose", "(J)V", (void*)nativeClose },
     { "nativeSetConfiguration", "(JLandroid/hardware/radio/RadioManager$BandConfig;)V",
             (void*)nativeSetConfiguration },
     { "nativeGetConfiguration", "(JI)Landroid/hardware/radio/RadioManager$BandConfig;",
             (void*)nativeGetConfiguration },
+    { "nativeStep", "(JZZ)V", (void*)nativeStep },
+    { "nativeScan", "(JZZ)V", (void*)nativeScan },
+    { "nativeTune", "(JII)V", (void*)nativeTune },
+    { "nativeCancel", "(J)V", (void*)nativeCancel },
+    { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
+            (void*)nativeGetProgramInformation },
 };
 
 } // namespace Tuner
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
index 54dd7df..4986091 100644
--- a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.cpp
@@ -49,10 +49,11 @@
 static struct {
     jmethodID onError;
     jmethodID onConfigurationChanged;
+    jmethodID onProgramInfoChanged;
 } gITunerCallbackMethods;
 
 // from frameworks/base/core/java/android/hardware/radio/RadioTuner.java
-enum class TunerError : int {
+enum class TunerError : jint {
     HARDWARE_FAILURE = 0,
     SERVER_DIED = 1,
     CANCELLED = 2,
@@ -60,8 +61,8 @@
     CONFIG = 4,
 };
 
-TunerCallback::TunerCallback(JNIEnv *env, jobject tuner, jobject clientCallback)
-        : mCallbackThread(gvm) {
+TunerCallback::TunerCallback(JNIEnv *env, jobject tuner, jobject clientCallback, HalRevision halRev)
+        : mCallbackThread(gvm), mHalRev(halRev) {
     ALOGV("TunerCallback()");
     mTuner = env->NewGlobalRef(tuner);
     mClientCallback = env->NewGlobalRef(clientCallback);
@@ -111,7 +112,35 @@
 }
 
 Return<void> TunerCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
-    ALOGE("Not implemented: tuneComplete");
+    ALOGV("tuneComplete(%d)", result);
+
+    if (mHalRev > HalRevision::V1_0) {
+        ALOGD("1.0 callback was ignored");
+        return Return<void>();
+    }
+
+    V1_1::ProgramInfo info_1_1 {
+        .base = info,
+    };
+    return tuneComplete_1_1(result, info_1_1);
+}
+
+Return<void> TunerCallback::tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info) {
+    ALOGV("tuneComplete_1_1(%d)", result);
+
+    mCallbackThread.enqueue([result, info, this](JNIEnv *env) {
+        if (result == Result::OK) {
+            auto jInfo = convert::ProgramInfoFromHal(env, info);
+            if (jInfo == nullptr) return;
+            env->CallVoidMethod(mClientCallback, gITunerCallbackMethods.onProgramInfoChanged,
+                    jInfo.get());
+        } else {
+            TunerError cause = TunerError::CANCELLED;
+            if (result == Result::TIMEOUT) cause = TunerError::SCAN_TIMEOUT;
+            env->CallVoidMethod(mClientCallback, gITunerCallbackMethods.onError, cause);
+        }
+    });
+
     return Return<void>();
 }
 
@@ -120,6 +149,11 @@
     return Return<void>();
 }
 
+Return<void> TunerCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
+    ALOGE("Not implemented: afSwitch_1_1");
+    return Return<void>();
+}
+
 Return<void> TunerCallback::antennaStateChange(bool connected) {
     ALOGE("Not implemented: antennaStateChange");
     return Return<void>();
@@ -141,16 +175,6 @@
     return Return<void>();
 }
 
-Return<void> TunerCallback::tuneComplete_1_1(Result result, const V1_1::ProgramInfo& info) {
-    ALOGE("Not implemented: tuneComplete_1_1");
-    return Return<void>();
-}
-
-Return<void> TunerCallback::afSwitch_1_1(const V1_1::ProgramInfo& info) {
-    ALOGE("Not implemented: afSwitch_1_1afSwitch_1_1");
-    return Return<void>();
-}
-
 Return<void> TunerCallback::backgroundScanAvailable(bool isAvailable) {
     ALOGE("Not implemented: backgroundScanAvailable");
     return Return<void>();
@@ -180,6 +204,8 @@
     gITunerCallbackMethods.onError = GetMethodIDOrDie(env, gITunerCallbackClass, "onError", "(I)V");
     gITunerCallbackMethods.onConfigurationChanged = GetMethodIDOrDie(env, gITunerCallbackClass,
             "onConfigurationChanged", "(Landroid/hardware/radio/RadioManager$BandConfig;)V");
+    gITunerCallbackMethods.onProgramInfoChanged = GetMethodIDOrDie(env, gITunerCallbackClass,
+            "onProgramInfoChanged", "(Landroid/hardware/radio/RadioManager$ProgramInfo;)V");
 }
 
 } // namespace android
diff --git a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
index 1c680b8..31208e9 100644
--- a/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
+++ b/services/core/jni/com_android_server_radio_Tuner_TunerCallback.h
@@ -18,6 +18,7 @@
 #define _ANDROID_SERVER_RADIO_TUNER_TUNERCALLBACK_H
 
 #include "NativeCallbackThread.h"
+#include "com_android_server_radio_types.h"
 
 #include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
 #include <jni.h>
@@ -34,11 +35,12 @@
     jobject mTuner;
     jobject mClientCallback;
     NativeCallbackThread mCallbackThread;
+    HalRevision mHalRev;
 
     DISALLOW_COPY_AND_ASSIGN(TunerCallback);
 
 public:
-    TunerCallback(JNIEnv *env, jobject tuner, jobject clientCallback);
+    TunerCallback(JNIEnv *env, jobject tuner, jobject clientCallback, HalRevision halRev);
     virtual ~TunerCallback();
 
     void detach();
diff --git a/services/core/jni/com_android_server_radio_convert.cpp b/services/core/jni/com_android_server_radio_convert.cpp
index 419e6d6..8ad899a 100644
--- a/services/core/jni/com_android_server_radio_convert.cpp
+++ b/services/core/jni/com_android_server_radio_convert.cpp
@@ -33,6 +33,8 @@
 
 using V1_0::Band;
 using V1_0::Deemphasis;
+using V1_0::Direction;
+using V1_0::MetadataType;
 using V1_0::Result;
 using V1_0::Rds;
 
@@ -62,10 +64,24 @@
         jfieldID upperLimit;
         jfieldID spacing;
     } BandDescriptor;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+    } ProgramInfo;
+
+    struct {
+        jclass clazz;
+        jmethodID cstor;
+        jmethodID putIntFromNative;
+        jmethodID putStringFromNative;
+        jmethodID putBitmapFromNative;
+        jmethodID putClockFromNative;
+    } RadioMetadata;
 } gjni;
 
 template <typename T>
-bool ThrowIfFailedCommon(JNIEnv *env, const hardware::Return<T> &hidlResult) {
+static bool ThrowIfFailedHidl(JNIEnv *env, const Return<T> &hidlResult) {
     if (hidlResult.isOk()) return false;
 
     jniThrowExceptionFmt(env, "java/lang/RuntimeException",
@@ -73,15 +89,8 @@
     return true;
 }
 
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult) {
-    return ThrowIfFailedCommon(env, hidlResult);
-}
-
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<V1_0::Result> &hidlResult) {
-    if (ThrowIfFailedCommon(env, hidlResult)) return true;
-
-    Result result = hidlResult;
-    switch (result) {
+static bool ThrowIfFailed(JNIEnv *env, const Result halResult) {
+    switch (halResult) {
         case Result::OK:
             return false;
         case Result::NOT_INITIALIZED:
@@ -100,11 +109,20 @@
             return true;
         default:
             jniThrowExceptionFmt(env, "java/lang/RuntimeException",
-                    "Unknown failure, result: %d", result);
+                    "Unknown failure, result: %d", halResult);
             return true;
     }
 }
 
+bool ThrowIfFailed(JNIEnv *env, const Return<void> &hidlResult, Result halResult) {
+    return ThrowIfFailedHidl(env, hidlResult) || ThrowIfFailed(env, halResult);
+}
+
+bool ThrowIfFailed(JNIEnv *env, const Return<Result> &hidlResult) {
+    return ThrowIfFailedHidl(env, hidlResult)
+            || ThrowIfFailed(env, static_cast<Result>(hidlResult));
+}
+
 static Rds RdsForRegion(bool rds, Region region) {
     if (!rds) return Rds::NONE;
 
@@ -137,7 +155,7 @@
     }
 }
 
-JavaRef BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
     ALOGV("BandConfigFromHal()");
     EnvWrapper wrap(env);
 
@@ -203,6 +221,77 @@
     return config;
 }
 
+Direction DirectionToHal(bool directionDown) {
+    return directionDown ? Direction::DOWN : Direction::UP;
+}
+
+static JavaRef<jobject> MetadataFromHal(JNIEnv *env, const hidl_vec<V1_0::MetaData> metadata) {
+    ALOGV("MetadataFromHal()");
+    EnvWrapper wrap(env);
+
+    if (metadata.size() == 0) return nullptr;
+
+    auto jMetadata = wrap(env->NewObject(gjni.RadioMetadata.clazz, gjni.RadioMetadata.cstor));
+
+    for (auto& item : metadata) {
+        jint key = static_cast<jint>(item.key);
+        jint status = 0;
+        switch (item.type) {
+            case MetadataType::INT:
+                ALOGV("metadata INT %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putIntFromNative,
+                        key, item.intValue);
+                break;
+            case MetadataType::TEXT: {
+                ALOGV("metadata TEXT %d", key);
+                auto value = wrap(env->NewStringUTF(item.stringValue.c_str()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putStringFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::RAW: {
+                ALOGV("metadata RAW %d", key);
+                auto len = item.rawValue.size();
+                if (len == 0) break;
+                auto value = wrap(env->NewByteArray(len));
+                if (value == nullptr) {
+                    ALOGE("Failed to allocate byte array of len %zu", len);
+                    break;
+                }
+                env->SetByteArrayRegion(value.get(), 0, len,
+                        reinterpret_cast<const jbyte*>(item.rawValue.data()));
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putBitmapFromNative,
+                        key, value.get());
+                break;
+            }
+            case MetadataType::CLOCK:
+                ALOGV("metadata CLOCK %d", key);
+                status = env->CallIntMethod(jMetadata.get(), gjni.RadioMetadata.putClockFromNative,
+                        key, item.clockValue.utcSecondsSinceEpoch,
+                        item.clockValue.timezoneOffsetInMinutes);
+                break;
+            default:
+                ALOGW("invalid metadata type %d", item.type);
+        }
+        ALOGE_IF(status != 0, "Failed inserting metadata %d (of type %d)", key, item.type);
+    }
+
+    return jMetadata;
+}
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info11) {
+    ALOGV("ProgramInfoFromHal()");
+    EnvWrapper wrap(env);
+
+    auto& info10 = info11.base;
+    auto jMetadata = MetadataFromHal(env, info10.metadata);
+    auto jVendorExtension = wrap(env->NewStringUTF(info11.vendorExension.c_str()));
+
+    return wrap(env->NewObject(gjni.ProgramInfo.clazz, gjni.ProgramInfo.cstor, info10.channel,
+            info10.subChannel, info10.tuned, info10.stereo, info10.digital, info10.signalStrength,
+            jMetadata.get(), info11.flags, jVendorExtension.get()));
+}
+
 
 } // namespace convert
 } // namespace radio
@@ -239,6 +328,23 @@
     gjni.BandDescriptor.lowerLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mLowerLimit", "I");
     gjni.BandDescriptor.upperLimit = GetFieldIDOrDie(env, bandDescriptorClass, "mUpperLimit", "I");
     gjni.BandDescriptor.spacing = GetFieldIDOrDie(env, bandDescriptorClass, "mSpacing", "I");
+
+    auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo");
+    gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass);
+    gjni.ProgramInfo.cstor = GetMethodIDOrDie(env, programInfoClass, "<init>",
+            "(IIZZZILandroid/hardware/radio/RadioMetadata;ILjava/lang/String;)V");
+
+    auto radioMetadataClass = FindClassOrDie(env, "android/hardware/radio/RadioMetadata");
+    gjni.RadioMetadata.clazz = MakeGlobalRefOrDie(env, radioMetadataClass);
+    gjni.RadioMetadata.cstor = GetMethodIDOrDie(env, radioMetadataClass, "<init>", "()V");
+    gjni.RadioMetadata.putIntFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putIntFromNative", "(II)I");
+    gjni.RadioMetadata.putStringFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putStringFromNative", "(ILjava/lang/String;)I");
+    gjni.RadioMetadata.putBitmapFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putBitmapFromNative", "(I[B)I");
+    gjni.RadioMetadata.putClockFromNative = GetMethodIDOrDie(env, radioMetadataClass,
+            "putClockFromNative", "(IJI)I");
 }
 
 } // namespace android
diff --git a/services/core/jni/com_android_server_radio_convert.h b/services/core/jni/com_android_server_radio_convert.h
index dba948e..811f653 100644
--- a/services/core/jni/com_android_server_radio_convert.h
+++ b/services/core/jni/com_android_server_radio_convert.h
@@ -34,11 +34,15 @@
 namespace V1_0 = hardware::broadcastradio::V1_0;
 namespace V1_1 = hardware::broadcastradio::V1_1;
 
-JavaRef BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<V1_0::Result> &hidlResult);
+bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult, V1_0::Result halResult);
+
+JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
 V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region);
 
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<V1_0::Result> &hidlResult);
-bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult);
+V1_0::Direction DirectionToHal(bool directionDown);
+
+JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_1::ProgramInfo &info);
 
 } // namespace convert
 } // namespace radio
diff --git a/services/core/jni/com_android_server_radio_types.h b/services/core/jni/com_android_server_radio_types.h
index 8430e05..36f7643 100644
--- a/services/core/jni/com_android_server_radio_types.h
+++ b/services/core/jni/com_android_server_radio_types.h
@@ -27,6 +27,11 @@
  * frameworks/base/core/java/android/hardware/radio/RadioManager.java.
  */
 
+enum class HalRevision : jint {
+    V1_0,
+    V1_1,
+};
+
 // Keep in sync with STATUS_* constants from RadioManager.java.
 enum class Status : jint {
     OK = 0,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9995a3c..3113cb3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -106,7 +106,6 @@
 import com.android.server.statusbar.StatusBarManagerService;
 import com.android.server.storage.DeviceStorageMonitorService;
 import com.android.server.telecom.TelecomLoaderService;
-import com.android.server.text.TextClassificationService;
 import com.android.server.trust.TrustManagerService;
 import com.android.server.tv.TvInputManagerService;
 import com.android.server.tv.TvRemoteService;
@@ -177,7 +176,7 @@
     private static final String JOB_SCHEDULER_SERVICE_CLASS =
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
-            "com.android.server.LockSettingsService$Lifecycle";
+            "com.android.server.locksettings.LockSettingsService$Lifecycle";
     private static final String STORAGE_MANAGER_SERVICE_CLASS =
             "com.android.server.StorageManagerService$Lifecycle";
     private static final String STORAGE_STATS_SERVICE_CLASS =
@@ -1053,12 +1052,6 @@
                 traceEnd();
             }
 
-            if (!disableNonCoreServices) {
-                traceBeginAndSlog("StartTextClassificationService");
-                mSystemServiceManager.startService(TextClassificationService.Lifecycle.class);
-                traceEnd();
-            }
-
             if (!disableNetwork) {
                 traceBeginAndSlog("StartNetworkScoreService");
                 try {
diff --git a/services/tests/notification/src/com/android/server/notification/BadgeExtractorTest.java b/services/tests/notification/src/com/android/server/notification/BadgeExtractorTest.java
index 2e8b068..0cf4994 100644
--- a/services/tests/notification/src/com/android/server/notification/BadgeExtractorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BadgeExtractorTest.java
@@ -69,7 +69,7 @@
         Notification n = builder.build();
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel, true);
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
         return r;
     }
 
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 5e8b3d4..d4904f5 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -259,7 +259,7 @@
 
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel, true);
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
         mService.addNotification(r);
         return r;
     }
@@ -769,7 +769,7 @@
 
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel, true);
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
         mService.addNotification(r);
 
         mService.buzzBeepBlinkLocked(r);
diff --git a/services/tests/notification/src/com/android/server/notification/GlobalSortKeyComparatorTest.java b/services/tests/notification/src/com/android/server/notification/GlobalSortKeyComparatorTest.java
index 33d2d07..24cb72e 100644
--- a/services/tests/notification/src/com/android/server/notification/GlobalSortKeyComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/GlobalSortKeyComparatorTest.java
@@ -53,21 +53,21 @@
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
         left.setGlobalSortKey("first");
 
         NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
         right.setGlobalSortKey("second");
 
         NotificationRecord last = new NotificationRecord(InstrumentationRegistry.getContext(),
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
 
 
         final List<NotificationRecord> expected = new ArrayList<>();
@@ -93,13 +93,13 @@
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
 
         NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
         right.setGlobalSortKey("not null");
 
         final List<NotificationRecord> expected = new ArrayList<>();
@@ -124,14 +124,14 @@
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
         left.setGlobalSortKey("not null");
 
         NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
                 new StatusBarNotification(PKG,
                         PKG, 1, "media", UID, UID, n,
                         new UserHandle(UserHandle.myUserId()),
-                        "", 1499), getDefaultChannel(), true);
+                        "", 1499), getDefaultChannel());
 
         final List<NotificationRecord> expected = new ArrayList<>();
         expected.add(left);
diff --git a/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
index 7a2dbaf..3dbd803 100644
--- a/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
@@ -71,7 +71,7 @@
         Notification n = builder.build();
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid,
                 mPid, n, mUser, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel, true);
+        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
         return r;
     }
 
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
index ccd2db0..dde08fc 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
@@ -76,7 +76,7 @@
     private NotificationRecord mRecordUrgent;
     private NotificationRecord mRecordCheater;
     private NotificationRecord mRecordCheaterColorized;
-
+    private NotificationRecord mNoMediaSessionMedia;
 
     @Before
     public void setUp() {
@@ -108,7 +108,7 @@
                 .build();
         mRecordMinCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
                 callPkg, 1, "minCall", callUid, callUid, n1,
-                new UserHandle(userId), "", 2000), getDefaultChannel(), false);
+                new UserHandle(userId), "", 2000), getDefaultChannel());
         mRecordMinCall.setUserImportance(NotificationManager.IMPORTANCE_MIN);
 
         Notification n2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -118,24 +118,23 @@
                 .build();
         mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
                 callPkg, 1, "highcall", callUid, callUid, n2,
-                new UserHandle(userId), "", 1999), getDefaultChannel(), false);
+                new UserHandle(userId), "", 1999), getDefaultChannel());
         mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
 
         Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.MediaStyle()
                         .setMediaSession(new MediaSession.Token(null)))
-                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                 .build();
         mRecordDefaultMedia = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "media", uid2, uid2, n3, new UserHandle(userId),
-                "", 1499), getDefaultChannel(), false);
+                "", 1499), getDefaultChannel());
         mRecordDefaultMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
         Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.MessagingStyle("sender!")).build();
         mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
-                "", 1599), getDefaultChannel(), false);
+                "", 1599), getDefaultChannel());
         mRecordInlineReply.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
         mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX);
 
@@ -143,27 +142,27 @@
                 .setCategory(Notification.CATEGORY_MESSAGE).build();
         mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg,
                 smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
-                "", 1299), getDefaultChannel(), false);
+                "", 1299), getDefaultChannel());
         mRecordSms.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
         Notification n6 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId),
-                "", 1259), getDefaultChannel(), false);
+                "", 1259), getDefaultChannel());
         mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT);
         mRecordStarredContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
         Notification n7 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId),
-                "", 1259), getDefaultChannel(), false);
+                "", 1259), getDefaultChannel());
         mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT);
         mRecordContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
         Notification n8 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
-                "", 1258), getDefaultChannel(), false);
+                "", 1258), getDefaultChannel());
         mRecordUrgent.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
 
         Notification n9 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -173,7 +172,7 @@
                 .build();
         mRecordCheater = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "cheater", uid2, uid2, n9, new UserHandle(userId),
-                "", 9258), getDefaultChannel(), false);
+                "", 9258), getDefaultChannel());
         mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW);
         mRecordCheater.setPackagePriority(Notification.PRIORITY_MAX);
 
@@ -181,7 +180,7 @@
                 .setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
         mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
-                "", 1599), getDefaultChannel(), false);
+                "", 1599), getDefaultChannel());
         mRecordEmail.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
 
         Notification n11 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -190,8 +189,18 @@
                 .build();
         mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId),
-                "", 9258), getDefaultChannel(), false);
+                "", 9258), getDefaultChannel());
         mRecordCheaterColorized.setUserImportance(NotificationManager.IMPORTANCE_LOW);
+
+        Notification n12 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                .setCategory(Notification.CATEGORY_MESSAGE)
+                .setColorized(true)
+                .setStyle(new Notification.MediaStyle())
+                .build();
+        mNoMediaSessionMedia = new NotificationRecord(mContext, new StatusBarNotification(
+                pkg2, pkg2, 1, "cheater", uid2, uid2, n12, new UserHandle(userId),
+                "", 9258), getDefaultChannel());
+        mNoMediaSessionMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
     }
 
     @Test
@@ -205,6 +214,7 @@
         expected.add(mRecordContact);
         expected.add(mRecordEmail);
         expected.add(mRecordUrgent);
+        expected.add(mNoMediaSessionMedia);
         expected.add(mRecordCheater);
         expected.add(mRecordCheaterColorized);
         expected.add(mRecordMinCall);
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index f3eb4f8..177c02d 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -165,7 +165,7 @@
 
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", uid, 0,
                 nb.build(), new UserHandle(uid), null, 0);
-        return new NotificationRecord(mContext, sbn, channel, true);
+        return new NotificationRecord(mContext, sbn, channel);
     }
     private NotificationRecord generateNotificationRecord(NotificationChannel channel) {
         return generateNotificationRecord(channel, null);
@@ -184,7 +184,7 @@
         }
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", uid, 0,
                 nb.build(), new UserHandle(uid), null, 0);
-        return new NotificationRecord(mContext, sbn, channel, true);
+        return new NotificationRecord(mContext, sbn, channel);
     }
 
     @Test
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index 66f3799..1c8ca84 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -21,6 +21,7 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -60,10 +61,6 @@
     private final Context mMockContext = Mockito.mock(Context.class);
     @Mock PackageManager mPm;
 
-    // constants for targetSdk version. N is pre channels, O is post.
-    private final boolean N = false;
-    private final boolean O = true;
-
     private final String pkg = "com.android.server.notification";
     private final int uid = 9583;
     private final String pkg2 = "pkg2";
@@ -79,6 +76,7 @@
             new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
                     NotificationManager.IMPORTANCE_UNSPECIFIED);
     private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+    final ApplicationInfo legacy = new ApplicationInfo();
     final ApplicationInfo upgrade = new ApplicationInfo();
 
     private static final long[] CUSTOM_VIBRATION = new long[] {
@@ -102,13 +100,17 @@
                 InstrumentationRegistry.getContext().getResources());
         when(mMockContext.getPackageManager()).thenReturn(mPm);
 
+        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
         upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
-        when(mMockContext.getApplicationInfo()).thenReturn(upgrade);
+        try {
+            when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy);
+            when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade);
+        } catch (PackageManager.NameNotFoundException e) {}
     }
 
-    private StatusBarNotification getNotification(boolean supportsChannels, boolean noisy,
-            boolean defaultSound, boolean buzzy, boolean defaultVibration, boolean lights,
-            boolean defaultLights) {
+    private StatusBarNotification getNotification(boolean preO, boolean noisy, boolean defaultSound,
+            boolean buzzy, boolean defaultVibration, boolean lights, boolean defaultLights) {
+        when(mMockContext.getApplicationInfo()).thenReturn(preO ? legacy : upgrade);
         final Builder builder = new Builder(mMockContext)
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
@@ -147,13 +149,13 @@
         }
 
         builder.setDefaults(defaults);
-        if (supportsChannels) {
+        if (!preO) {
             builder.setChannelId(channelId);
         }
 
 
         Notification n = builder.build();
-        if (!supportsChannels) {
+        if (preO) {
             return new StatusBarNotification(pkg, pkg, id1, tag1, uid, uid, n,
                     mUser, null, uid);
         } else {
@@ -170,11 +172,11 @@
     public void testSound_default_preUpgradeUsesNotification() throws Exception {
         defaultChannel.setSound(null, null);
         // pre upgrade, default sound.
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, record.getSound());
         assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, record.getAudioAttributes());
     }
@@ -183,11 +185,11 @@
     public void testSound_custom_preUpgradeUsesNotification() throws Exception {
         defaultChannel.setSound(null, null);
         // pre upgrade, custom sound.
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(CUSTOM_SOUND, record.getSound());
         assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
     }
@@ -197,11 +199,11 @@
         defaultChannel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
         // pre upgrade, default sound.
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(CUSTOM_SOUND, record.getSound());
         assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
     }
@@ -209,11 +211,11 @@
     @Test
     public void testSound_noSound_preUpgrade() throws Exception {
         // pre upgrade, default sound.
-        StatusBarNotification sbn = getNotification(N, false /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
                 false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(null, record.getSound());
         assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, record.getAudioAttributes());
     }
@@ -222,11 +224,11 @@
     public void testSound_default_upgradeUsesChannel() throws Exception {
         channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
         // post upgrade, default sound.
-        StatusBarNotification sbn = getNotification(O, true /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
         assertEquals(CUSTOM_SOUND, record.getSound());
         assertEquals(CUSTOM_ATTRIBUTES, record.getAudioAttributes());
     }
@@ -235,11 +237,11 @@
     public void testVibration_default_preUpgradeUsesNotification() throws Exception {
         defaultChannel.enableVibration(false);
         // pre upgrade, default vibration.
-        StatusBarNotification sbn = getNotification(N, false /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
                 false /* defaultSound */, true /* buzzy */, true /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertNotNull(record.getVibration());
     }
 
@@ -247,11 +249,11 @@
     public void testVibration_custom_preUpgradeUsesNotification() throws Exception {
         defaultChannel.enableVibration(false);
         // pre upgrade, custom vibration.
-        StatusBarNotification sbn = getNotification(N, false /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
                 false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(CUSTOM_VIBRATION, record.getVibration());
     }
 
@@ -260,11 +262,11 @@
         defaultChannel.enableVibration(true);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
         // pre upgrade, custom vibration.
-        StatusBarNotification sbn = getNotification(N, false /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
                 false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
     }
 
@@ -272,20 +274,20 @@
     public void testVibration_custom_upgradeUsesChannel() throws Exception {
         channel.enableVibration(true);
         // post upgrade, custom vibration.
-        StatusBarNotification sbn = getNotification(O, false /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, false /* noisy */,
                 false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
         assertEquals(CUSTOM_CHANNEL_VIBRATION, record.getVibration());
     }
 
     @Test
     public void testImportance_preUpgrade() throws Exception {
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
     }
 
@@ -293,11 +295,11 @@
     public void testImportance_locked_preUpgrade() throws Exception {
         defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(NotificationManager.IMPORTANCE_LOW, record.getImportance());
     }
 
@@ -305,39 +307,39 @@
     public void testImportance_locked_unspecified_preUpgrade() throws Exception {
         defaultChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
 
-        NotificationRecord record =  new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
     }
 
     @Test
     public void testImportance_upgrade() throws Exception {
-        StatusBarNotification sbn = getNotification(O, true /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
         assertEquals(NotificationManager.IMPORTANCE_DEFAULT, record.getImportance());
     }
 
     @Test
     public void testLights_preUpgrade_noLight() throws Exception {
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertNull(record.getLight());
     }
 
 
     @Test
     public void testLights_preUpgrade() throws Exception {
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 true /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertEquals(CUSTOM_LIGHT, record.getLight());
     }
 
@@ -345,11 +347,11 @@
     public void testLights_locked_preUpgrade() throws Exception {
         defaultChannel.enableLights(true);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
-        StatusBarNotification sbn = getNotification(N, true /* noisy */,
+        StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 true /* lights */, false /*defaultLights */);
 
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, N);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertFalse(CUSTOM_LIGHT.equals(record.getLight()));
     }
 
@@ -364,10 +366,10 @@
 
         NotificationRecord.Light expected = new NotificationRecord.Light(
                 defaultLightColor, defaultLightOn, defaultLightOff);
-        StatusBarNotification sbn = getNotification(O, true /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 true /* lights */, true /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
         assertEquals(expected, record.getLight());
     }
 
@@ -380,19 +382,19 @@
 
         NotificationRecord.Light expected = new NotificationRecord.Light(
                 Color.BLUE, defaultLightOn, defaultLightOff);
-        StatusBarNotification sbn = getNotification(O, true /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 true /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
         assertEquals(expected, record.getLight());
     }
 
     @Test
     public void testLights_upgrade_noLight() throws Exception {
-        StatusBarNotification sbn = getNotification(O, true /* noisy */,
+        StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */);
-        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel, O);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
         assertNull(record.getLight());
     }
 }
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index 8ab6d08..7bef033 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -124,7 +124,7 @@
                 .build();
         mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, mNotiGroupGSortA, user,
-                null, System.currentTimeMillis()), getDefaultChannel(), false);
+                null, System.currentTimeMillis()), getDefaultChannel());
 
         mNotiGroupGSortB = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("B")
@@ -134,7 +134,7 @@
                 .build();
         mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, mNotiGroupGSortB, user,
-                null, System.currentTimeMillis()), getDefaultChannel(), false);
+                null, System.currentTimeMillis()), getDefaultChannel());
 
         mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("C")
@@ -142,7 +142,7 @@
                 .build();
         mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, mNotiNoGroup, user,
-                null, System.currentTimeMillis()), getDefaultChannel(), false);
+                null, System.currentTimeMillis()), getDefaultChannel());
 
         mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("D")
@@ -150,7 +150,7 @@
                 .build();
         mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
-                null, System.currentTimeMillis()), getDefaultChannel(), false);
+                null, System.currentTimeMillis()), getDefaultChannel());
 
         mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("E")
@@ -159,7 +159,7 @@
                 .build();
         mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                 "package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user,
-                null, System.currentTimeMillis()), getDefaultChannel(), false);
+                null, System.currentTimeMillis()), getDefaultChannel());
 
         mAudioAttributes = new AudioAttributes.Builder()
                 .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
@@ -373,7 +373,7 @@
         assertNull(mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
         assertNull(mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
         assertNull(mHelper.getNotificationChannelGroup(ncg.getId(), PKG, UID));
-        assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
+        //assertEquals(ncg2, mHelper.getNotificationChannelGroup(ncg2.getId(), PKG, UID));
         assertEquals(channel2, mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
     }
 
@@ -696,14 +696,20 @@
         // Returns only non-deleted channels
         List<NotificationChannel> channels =
                 mHelper.getNotificationChannels(PKG, UID, false).getList();
-        assertEquals(1, channels.size());
-        compareChannels(channel2, channels.get(0));
+        assertEquals(2, channels.size());   // Default channel + non-deleted channel
+        for (NotificationChannel nc : channels) {
+            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
+                compareChannels(channel2, nc);
+            }
+        }
 
         // Returns deleted channels too
         channels = mHelper.getNotificationChannels(PKG, UID, true).getList();
-        assertEquals(2, channels.size());
+        assertEquals(3, channels.size());               // Includes default channel
         for (NotificationChannel nc : channels) {
-            compareChannels(channelMap.get(nc.getId()), nc);
+            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
+                compareChannels(channelMap.get(nc.getId()), nc);
+            }
         }
     }
 
@@ -801,8 +807,8 @@
 
         mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
 
-        // No channels remain
-        assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
+        // Only default channel remains
+        assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
     }
 
     @Test
@@ -881,32 +887,13 @@
 
         mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
 
-        // since this is a pre upgrade app, clearing data should restore the default channel
-        assertEquals(1, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
-        assertEquals(NotificationChannel.DEFAULT_CHANNEL_ID,
-                mHelper.getNotificationChannels(PKG, UID, true).getList().get(0).getId());
+        assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
 
         // Not deleted
         mHelper.createNotificationChannel(PKG, UID, channel1, true);
+
         mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
-        assertEquals(1, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
-    }
-
-    @Test
-    public void testOnPackageChanged_packageRemoval_updatedPackage() throws Exception {
-        // Deleted
-        NotificationChannel channel1 =
-                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(UPDATED_PKG, UID2, channel1, true);
-        mHelper.onPackagesChanged(
-                true, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
-        assertEquals(0, mHelper.getNotificationChannels(UPDATED_PKG, UID2, true).getList().size());
-
-        // Not deleted
-        mHelper.createNotificationChannel(UPDATED_PKG, UID2, channel1, true);
-        mHelper.onPackagesChanged(
-                false, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
-        assertEquals(1, mHelper.getNotificationChannels(UPDATED_PKG, UID2, false).getList().size());
+        assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
     }
 
     @Test
@@ -927,23 +914,7 @@
 
         mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
 
-        // default channel restored
-        assertEquals(1, mHelper.getNotificationChannelGroups(PKG, UID, true).getList().size());
-        assertNull(mHelper.getNotificationChannelGroups(PKG, UID, true).getList().get(0).getId());
-    }
-
-    @Test
-    public void testOnPackageChanged_packageRemoval_groups_upgraded() throws Exception {
-        NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
-        mHelper.createNotificationChannelGroup(UPDATED_PKG, UID2, ncg, true);
-        NotificationChannelGroup ncg2 = new NotificationChannelGroup("group2", "name2");
-        mHelper.createNotificationChannelGroup(UPDATED_PKG, UID2, ncg2, true);
-
-        mHelper.onPackagesChanged(
-                true, UserHandle.USER_SYSTEM, new String[]{UPDATED_PKG}, new int[]{UID2});
-
-        assertEquals(0,
-                mHelper.getNotificationChannelGroups(UPDATED_PKG, UID2, true).getList().size());
+        assertEquals(0, mHelper.getNotificationChannelGroups(PKG, UID, true).getList().size());
     }
 
     @Test
@@ -1017,8 +988,9 @@
         assertEquals(3, actual.size());
         for (NotificationChannelGroup group : actual) {
             if (group.getId() == null) {
-                assertEquals(1, group.getChannels().size());
-                assertTrue(channel3.getId().equals(group.getChannels().get(0).getId()));
+                assertEquals(2, group.getChannels().size()); // misc channel too
+                assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
+                        || channel3.getId().equals(group.getChannels().get(1).getId()));
             } else if (group.getId().equals(ncg.getId())) {
                 assertEquals(2, group.getChannels().size());
                 if (group.getChannels().get(0).getId().equals(channel1.getId())) {
@@ -1052,8 +1024,12 @@
         List<NotificationChannelGroup> actual =
                 mHelper.getNotificationChannelGroups(PKG, UID, true).getList();
 
-        assertEquals(1, actual.size());
-        assertEquals(1, actual.get(0).getChannels().size());
+        assertEquals(2, actual.size());
+        for (NotificationChannelGroup group : actual) {
+            if (Objects.equals(group.getId(), ncg.getId())) {
+                assertEquals(1, group.getChannels().size());
+            }
+        }
     }
 
     @Test
diff --git a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
index b1cb4d7..bc25860 100644
--- a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
@@ -312,7 +312,7 @@
                 TEST_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_LOW);
         return new NotificationRecord(getContext(), new StatusBarNotification(
                 pkg, pkg, id, tag, 0, 0, n, user, null,
-                System.currentTimeMillis()), notificationChannel, true);
+                System.currentTimeMillis()), notificationChannel);
     }
 
     private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
diff --git a/services/tests/servicestests/res/raw/backup_telephony_no_password b/services/tests/servicestests/res/raw/backup_telephony_no_password
new file mode 100644
index 0000000..12b6cbf
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_no_password
Binary files differ
diff --git a/services/tests/servicestests/res/raw/backup_telephony_with_password b/services/tests/servicestests/res/raw/backup_telephony_with_password
new file mode 100644
index 0000000..ce847a3
--- /dev/null
+++ b/services/tests/servicestests/res/raw/backup_telephony_with_password
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
deleted file mode 100644
index 7167e8c..0000000
--- a/services/tests/servicestests/src/com/android/server/BaseLockSettingsServiceTests.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.IActivityManager;
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.pm.UserInfo;
-import android.os.FileUtils;
-import android.os.IProgressListener;
-import android.os.UserManager;
-import android.security.KeyStore;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-
-public class BaseLockSettingsServiceTests extends AndroidTestCase {
-    protected static final int PRIMARY_USER_ID = 0;
-    protected static final int MANAGED_PROFILE_USER_ID = 12;
-    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
-    protected static final int SECONDARY_USER_ID = 20;
-
-    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
-    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED);
-
-    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
-
-    LockSettingsService mService;
-
-    MockLockSettingsContext mContext;
-    LockSettingsStorageTestable mStorage;
-
-    LockPatternUtils mLockPatternUtils;
-    MockGateKeeperService mGateKeeperService;
-    NotificationManager mNotificationManager;
-    UserManager mUserManager;
-    MockStorageManager mStorageManager;
-    IActivityManager mActivityManager;
-    DevicePolicyManager mDevicePolicyManager;
-    KeyStore mKeyStore;
-    MockSyntheticPasswordManager mSpManager;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mLockPatternUtils = mock(LockPatternUtils.class);
-        mGateKeeperService = new MockGateKeeperService();
-        mNotificationManager = mock(NotificationManager.class);
-        mUserManager = mock(UserManager.class);
-        mStorageManager = new MockStorageManager();
-        mActivityManager = mock(IActivityManager.class);
-        mDevicePolicyManager = mock(DevicePolicyManager.class);
-
-        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
-                mDevicePolicyManager);
-        mStorage = new LockSettingsStorageTestable(mContext,
-                new File(getContext().getFilesDir(), "locksettings"));
-        File storageDir = mStorage.mStorageDir;
-        if (storageDir.exists()) {
-            FileUtils.deleteContents(storageDir);
-        } else {
-            storageDir.mkdirs();
-        }
-
-        mSpManager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
-        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
-                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager,
-                mSpManager);
-        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
-        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
-        installChildProfile(MANAGED_PROFILE_USER_ID);
-        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
-        when(mUserManager.getUsers(anyBoolean())).thenReturn(mPrimaryUserProfiles);
-        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
-        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
-
-        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
-                new Answer<Boolean>() {
-            @Override
-            public Boolean answer(InvocationOnMock invocation) throws Throwable {
-                Object[] args = invocation.getArguments();
-                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
-                        (IProgressListener) args[3]);
-                return true;
-            }
-        });
-
-        when(mLockPatternUtils.getLockSettings()).thenReturn(mService);
-
-        // Adding a fake Device Owner app which will enable escrow token support in LSS.
-        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
-                new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
-    }
-
-    private UserInfo installChildProfile(int profileId) {
-        final UserInfo userInfo = new UserInfo(
-            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
-        mPrimaryUserProfiles.add(userInfo);
-        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
-        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
-        return userInfo;
-    }
-
-    private UserInfo installAndTurnOffChildProfile(int profileId) {
-        final UserInfo userInfo = installChildProfile(profileId);
-        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
-        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
-        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
-        return userInfo;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-        File db = getContext().getDatabasePath("locksettings.db");
-        assertTrue(!db.exists() || db.delete());
-
-        File storageDir = mStorage.mStorageDir;
-        assertTrue(FileUtils.deleteContents(storageDir));
-    }
-
-    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
-        assertTrue(Arrays.equals(expected, actual));
-    }
-
-    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
-        assertFalse(Arrays.equals(expected, actual));
-    }
-}
-
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
deleted file mode 100644
index be88927..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTestable.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static org.mockito.Mockito.mock;
-
-import android.app.IActivityManager;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.storage.IStorageManager;
-import android.security.KeyStore;
-import android.security.keystore.KeyPermanentlyInvalidatedException;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.FileNotFoundException;
-
-public class LockSettingsServiceTestable extends LockSettingsService {
-
-    private static class MockInjector extends LockSettingsService.Injector {
-
-        private LockSettingsStorage mLockSettingsStorage;
-        private KeyStore mKeyStore;
-        private IActivityManager mActivityManager;
-        private LockPatternUtils mLockPatternUtils;
-        private IStorageManager mStorageManager;
-        private SyntheticPasswordManager mSpManager;
-
-        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
-                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
-                IStorageManager storageManager, SyntheticPasswordManager spManager) {
-            super(context);
-            mLockSettingsStorage = storage;
-            mKeyStore = keyStore;
-            mActivityManager = activityManager;
-            mLockPatternUtils = lockPatternUtils;
-            mStorageManager = storageManager;
-            mSpManager = spManager;
-        }
-
-        @Override
-        public Handler getHandler() {
-            return mock(Handler.class);
-        }
-
-        @Override
-        public LockSettingsStorage getStorage() {
-            return mLockSettingsStorage;
-        }
-
-        @Override
-        public LockSettingsStrongAuth getStrongAuth() {
-            return mock(LockSettingsStrongAuth.class);
-        }
-
-        @Override
-        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
-            return mock(SynchronizedStrongAuthTracker.class);
-        }
-
-        @Override
-        public IActivityManager getActivityManager() {
-            return mActivityManager;
-        }
-
-        @Override
-        public LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        public KeyStore getKeyStore() {
-            return mKeyStore;
-        }
-
-        @Override
-        public IStorageManager getStorageManager() {
-            return mStorageManager;
-        }
-
-        @Override
-        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
-            return mSpManager;
-        }
-
-        @Override
-        public int binderGetCallingUid() {
-            return Process.SYSTEM_UID;
-        }
-
-
-    }
-
-    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
-            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
-            IStorageManager storageManager, IActivityManager mActivityManager,
-            SyntheticPasswordManager spManager) {
-        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
-                storageManager, spManager));
-        mGateKeeperService = gatekeeper;
-    }
-
-    @Override
-    protected void tieProfileLockToParent(int userId, String password) {
-        mStorage.writeChildProfileLock(userId, password.getBytes());
-    }
-
-    @Override
-    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException,
-            KeyPermanentlyInvalidatedException {
-        byte[] storedData = mStorage.readChildProfileLock(userId);
-        if (storedData == null) {
-            throw new FileNotFoundException("Child profile lock file not found");
-        }
-        try {
-            if (mGateKeeperService.getSecureUserId(userId) == 0) {
-                throw new KeyPermanentlyInvalidatedException();
-            }
-        } catch (RemoteException e) {
-            // shouldn't happen.
-        }
-        return new String(storedData);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
deleted file mode 100644
index 25cc426..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsServiceTests.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import com.android.server.MockGateKeeperService.VerifyHandle;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsServiceTests
- */
-public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testCreatePasswordPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testCreatePatternPrimaryUser() throws RemoteException {
-        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
-                "asdfghjk", CREDENTIAL_TYPE_PASSWORD);
-    }
-
-    public void testChangePatternPrimaryUser() throws RemoteException {
-        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
-                "1596321", CREDENTIAL_TYPE_PATTERN);
-    }
-
-    public void testChangePasswordFailPrimaryUser() throws RemoteException {
-        final long sid = 1234;
-        final String FAILED_MESSAGE = "Failed to enroll password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
-
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
-                    PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
-        try {
-            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-            fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
-            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
-        }
-        assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
-    }
-
-    public void testClearPasswordPrimaryUser() throws RemoteException {
-        final String PASSWORD = "password";
-        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
-        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD, PRIMARY_USER_ID);
-        assertFalse(mService.havePassword(PRIMARY_USER_ID));
-        assertFalse(mService.havePattern(PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testManagedProfileUnifiedChallenge() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final long turnedOffProfileSid =
-                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-        assertTrue(turnedOffProfileSid != 0);
-        assertTrue(turnedOffProfileSid != primarySid);
-        assertTrue(turnedOffProfileSid != profileSid);
-
-        // clear auth token and wait for verify challenge from primary user to re-generate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
-        // verify credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-
-        // Verify that we have a new auth token for the profile
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
-        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
-
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        // Change primary password and verify that profile SID remains
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                UnifiedPassword, PRIMARY_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
-
-        // Clear unified challenge
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, UnifiedPassword,
-                PRIMARY_USER_ID);
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
-    }
-
-    public void testManagedProfileSeparateChallenge() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
-        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
-         * credential as part of verifyCredential() before the new credential is committed in
-         * StorageManager. So we relax the check in our mock StorageManager to allow that.
-         */
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                MANAGED_PROFILE_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // clear auth token and make sure verify challenge from primary user does not regenerate it.
-        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
-        // verify primary credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
-                .getResponseCode());
-        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-
-        // verify profile credential
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-
-        // Change primary credential and make sure we don't affect profile
-        mStorageManager.setIgnoreBadUnlock(true);
-        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                primaryPassword, PRIMARY_USER_ID);
-        mStorageManager.setIgnoreBadUnlock(false);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
-                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-    }
-
-    private void testCreateCredential(int userId, String credential, int type)
-            throws RemoteException {
-        mService.setLockCredential(credential, type, null, userId);
-        assertVerifyCredentials(userId, credential, type, -1);
-    }
-
-    private void testChangeCredentials(int userId, String newCredential, int newType,
-            String oldCredential, int oldType) throws RemoteException {
-        final long sid = 1234;
-        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
-        mService.setLockCredential(newCredential, newType, oldCredential, userId);
-        assertVerifyCredentials(userId, newCredential, newType, sid);
-    }
-
-    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
-            throws RemoteException{
-        final long challenge = 54321;
-        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
-                userId);
-
-        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
-        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
-        final int incorrectType;
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            assertTrue(mService.havePassword(userId));
-            assertFalse(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
-        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
-            assertFalse(mService.havePassword(userId));
-            assertTrue(mService.havePattern(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        } else {
-            assertFalse(mService.havePassword(userId));
-            assertFalse(mService.havePassword(userId));
-            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
-        }
-        // check for bad type
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
-                incorrectType, challenge, userId).getResponseCode());
-        // check for bad credential
-        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
-                type, challenge, userId).getResponseCode());
-    }
-
-    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
-        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
-        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
-        } else {
-            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
-                    LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
deleted file mode 100644
index 84ebb19..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
-import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
-
-import static com.android.internal.widget.LockPatternUtils.stringToPattern;
-
-import static junit.framework.Assert.*;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.io.FileDescriptor.*;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.os.Binder;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.FileDescriptor;
-
-/**
- * Test class for {@link LockSettingsShellCommand}.
- *
- * runtest frameworks-services -c com.android.server.LockSettingsShellCommandTest
- */
-@SmallTest
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class LockSettingsShellCommandTest {
-
-    private LockSettingsShellCommand mCommand;
-
-    private @Mock LockPatternUtils mLockPatternUtils;
-    private int mUserId;
-    private final Binder mBinder = new Binder();
-    private final ShellCallback mShellCallback = new ShellCallback();
-    private final ResultReceiver mResultReceiver = new ResultReceiver(
-            new Handler(Looper.getMainLooper()));
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mUserId = ActivityManager.getCurrentUser();
-        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
-    }
-
-    @Test
-    public void testWrongPassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
-        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
-                new String[] { "set-pin", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
-    }
-
-    @Test
-    public void testChangePin() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pin", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePassword() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
-        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-password", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
-                mUserId);
-    }
-
-    @Test
-    public void testChangePattern() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "set-pattern", "--old", "1234", "4321" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
-    }
-
-    @Test
-    public void testClear() throws Exception {
-        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
-        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
-        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
-        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
-                new String[] { "clear", "--old", "1234" },
-                mShellCallback, mResultReceiver));
-        verify(mLockPatternUtils).clearLock("1234", mUserId);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
deleted file mode 100644
index 18da1a5..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTestable.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import android.content.Context;
-
-import java.io.File;
-
-public class LockSettingsStorageTestable extends LockSettingsStorage {
-
-    public File mStorageDir;
-
-    public LockSettingsStorageTestable(Context context, File storageDir) {
-        super(context);
-        mStorageDir = storageDir;
-    }
-
-    @Override
-    String getLockPatternFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPatternFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getLockPasswordFilename(int userId) {
-        return makeDirs(mStorageDir,
-                super.getLockPasswordFilename(userId)).getAbsolutePath();
-    }
-
-    @Override
-    String getChildProfileLockFile(int userId) {
-        return makeDirs(mStorageDir,
-                super.getChildProfileLockFile(userId)).getAbsolutePath();
-    }
-
-    @Override
-    protected File getSyntheticPasswordDirectoryForUser(int userId) {
-        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
-                userId).getAbsolutePath());
-    }
-
-    private File makeDirs(File baseDir, String filePath) {
-        File path = new File(filePath);
-        if (path.getParent() == null) {
-            return new File(baseDir, filePath);
-        } else {
-            File mappedDir = new File(baseDir, path.getParent());
-            mappedDir.mkdirs();
-            return new File(mappedDir, path.getName());
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
deleted file mode 100644
index 4677904..0000000
--- a/services/tests/servicestests/src/com/android/server/LockSettingsStorageTests.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.UserInfo;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.FileUtils;
-import android.os.UserManager;
-import android.test.AndroidTestCase;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.LockSettingsStorage.CredentialHash;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
- */
-public class LockSettingsStorageTests extends AndroidTestCase {
-    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
-    private final byte[] PASSWORD_1 = "password1".getBytes();
-    private final byte[] PATTERN_0 = "123654".getBytes();
-    private final byte[] PATTERN_1 = "147852369".getBytes();
-
-    LockSettingsStorage mStorage;
-    File mStorageDir;
-
-    private File mDb;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
-        mDb = getContext().getDatabasePath("locksettings.db");
-
-        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
-        assertTrue(FileUtils.deleteContents(mStorageDir));
-        assertTrue(!mDb.exists() || mDb.delete());
-
-        final UserManager mockUserManager = mock(UserManager.class);
-        // User 2 is a profile of user 1.
-        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
-        // User 3 is a profile of user 0.
-        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
-
-        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
-                mock(NotificationManager.class), mock(DevicePolicyManager.class));
-        mStorage = new LockSettingsStorageTestable(context,
-                new File(getContext().getFilesDir(), "locksettings"));
-        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
-                    @Override
-                    public void initialize(SQLiteDatabase db) {
-                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
-                    }
-                });
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mStorage.closeDatabase();
-    }
-
-    public void testKeyValue_InitializeWorked() {
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-        mStorage.clearCache();
-        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
-    }
-
-    public void testKeyValue_WriteThenRead() {
-        mStorage.writeKeyValue("key", "value", 0);
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-        mStorage.clearCache();
-        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
-    }
-
-    public void testKeyValue_DefaultValue() {
-        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
-        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
-    }
-
-    public void testKeyValue_Concurrency() {
-        final Object monitor = new Object();
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    synchronized (monitor) {
-                        try {
-                            monitor.wait();
-                        } catch (InterruptedException e) {
-                            return;
-                        }
-                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
-                        mStorage.readKeyValue("key", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        mStorage.writeKeyValue("key", "initalValue", 0);
-        synchronized (monitor) {
-            monitor.notifyAll();
-        }
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-        mStorage.clearCache();
-        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
-    }
-
-    public void testKeyValue_CacheStarvedWriter() {
-        final CountDownLatch latch = new CountDownLatch(1);
-        List<Thread> threads = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            final int threadId = i;
-            threads.add(new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        latch.await();
-                    } catch (InterruptedException e) {
-                        return;
-                    }
-                    if (threadId == 50) {
-                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
-                    } else {
-                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
-                    }
-                }
-            });
-            threads.get(i).start();
-        }
-        latch.countDown();
-        for (int i = 0; i < threads.size(); i++) {
-            try {
-                threads.get(i).join();
-            } catch (InterruptedException e) {
-            }
-        }
-        String cached = mStorage.readKeyValue("key", "default", 0);
-        mStorage.clearCache();
-        String storage = mStorage.readKeyValue("key", "default", 0);
-        assertEquals("Cached value didn't match stored value", storage, cached);
-    }
-
-    public void testRemoveUser() {
-        mStorage.writeKeyValue("key", "value", 0);
-        writePasswordBytes(PASSWORD_0, 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.writeKeyValue("key", "value", 1);
-        writePasswordBytes(PASSWORD_1, 1);
-        writePatternBytes(PATTERN_1, 1);
-
-        mStorage.removeUser(0);
-
-        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
-        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
-        assertPatternBytes(PATTERN_1, 1);
-    }
-
-    public void testCredential_Default() {
-        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
-    }
-
-    public void testPassword_Write() {
-        writePasswordBytes(PASSWORD_0, 0);
-
-        assertPasswordBytes(PASSWORD_0, 0);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 0);
-    }
-
-    public void testPassword_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 1);
-        writePasswordBytes(PASSWORD_1, 2);
-
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_0, 1);
-        assertPasswordBytes(PASSWORD_1, 2);
-    }
-
-    public void testLockType_WriteProfileWritesParent() {
-        writePasswordBytes(PASSWORD_0, 10);
-        writePatternBytes(PATTERN_0, 20);
-
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-        mStorage.clearCache();
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                mStorage.readCredentialHash(10).type);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                mStorage.readCredentialHash(20).type);
-    }
-
-    public void testPassword_WriteParentWritesProfile() {
-        writePasswordBytes(PASSWORD_0, 2);
-        writePasswordBytes(PASSWORD_1, 1);
-
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-        mStorage.clearCache();
-        assertPasswordBytes(PASSWORD_1, 1);
-        assertPasswordBytes(PASSWORD_0, 2);
-    }
-
-    public void testProfileLock_ReadWriteChildProfileLock() {
-        assertFalse(mStorage.hasChildProfileLock(20));
-        mStorage.writeChildProfileLock(20, PASSWORD_0);
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-        mStorage.clearCache();
-        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
-        assertTrue(mStorage.hasChildProfileLock(20));
-    }
-
-    public void testPattern_Write() {
-        writePatternBytes(PATTERN_0, 0);
-
-        assertPatternBytes(PATTERN_0, 0);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testPattern_WriteProfileWritesParent() {
-        writePatternBytes(PATTERN_0, 1);
-        writePatternBytes(PATTERN_1, 2);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPattern_WriteParentWritesProfile() {
-        writePatternBytes(PATTERN_1, 2);
-        writePatternBytes(PATTERN_0, 1);
-
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-        mStorage.clearCache();
-        assertPatternBytes(PATTERN_0, 1);
-        assertPatternBytes(PATTERN_1, 2);
-    }
-
-    public void testPrefetch() {
-        mStorage.writeKeyValue("key", "toBeFetched", 0);
-        writePatternBytes(PATTERN_0, 0);
-
-        mStorage.clearCache();
-        mStorage.prefetchUser(0);
-
-        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
-        assertPatternBytes(PATTERN_0, 0);
-    }
-
-    public void testFileLocation_Owner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
-        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
-        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
-        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
-    }
-
-    public void testFileLocation_SecondaryUser() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
-        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
-    }
-
-    public void testFileLocation_ProfileToSecondary() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
-        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
-    }
-
-    public void testFileLocation_ProfileToOwner() {
-        LockSettingsStorage storage = new LockSettingsStorage(getContext());
-
-        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
-        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
-    }
-
-    public void testSyntheticPasswordState() {
-        final byte[] data = {1,2,3,4};
-        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
-        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
-
-        mStorage.deleteSyntheticPasswordState(10, 1234L, "state", true);
-        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
-    }
-
-    private static void assertArrayEquals(byte[] expected, byte[] actual) {
-        if (!Arrays.equals(expected, actual)) {
-            fail("expected:<" + Arrays.toString(expected) +
-                    "> but was:<" + Arrays.toString(actual) + ">");
-        }
-    }
-
-    private void writePasswordBytes(byte[] password, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
-    }
-
-    private void writePatternBytes(byte[] pattern, int userId) {
-        mStorage.writeCredentialHash(CredentialHash.create(
-                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
-    }
-
-    private void assertPasswordBytes(byte[] password, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
-        assertArrayEquals(password, cred.hash);
-    }
-
-    private void assertPatternBytes(byte[] pattern, int userId) {
-        CredentialHash cred = mStorage.readCredentialHash(userId);
-        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
-        assertArrayEquals(pattern, cred.hash);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
deleted file mode 100644
index bc93341..0000000
--- a/services/tests/servicestests/src/com/android/server/MockGateKeeperService.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.service.gatekeeper.GateKeeperResponse;
-import android.service.gatekeeper.IGateKeeperService;
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-public class MockGateKeeperService implements IGateKeeperService {
-    static class VerifyHandle {
-        public byte[] password;
-        public long sid;
-
-        public VerifyHandle(byte[] password, long sid) {
-            this.password = password;
-            this.sid = sid;
-        }
-
-        public VerifyHandle(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            sid = buffer.getLong();
-            password = new byte[buffer.remaining()];
-            buffer.get(password);
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
-            buffer.put((byte)0);
-            buffer.putLong(sid);
-            buffer.put(password);
-            return buffer.array();
-        }
-    }
-
-    static class AuthToken {
-        public long challenge;
-        public long sid;
-
-        public AuthToken(long challenge, long sid) {
-            this.challenge = challenge;
-            this.sid = sid;
-        }
-
-        public AuthToken(byte[] handle) {
-            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
-            buffer.put(handle, 0, handle.length);
-            buffer.flip();
-            int version = buffer.get();
-            challenge = buffer.getLong();
-            sid = buffer.getLong();
-        }
-
-        public byte[] toBytes() {
-            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
-            buffer.put((byte)0);
-            buffer.putLong(challenge);
-            buffer.putLong(sid);
-            return buffer.array();
-        }
-    }
-
-    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
-    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
-
-    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
-
-    @Override
-    public GateKeeperResponse enroll(int uid, byte[] currentPasswordHandle, byte[] currentPassword,
-            byte[] desiredPassword) throws android.os.RemoteException {
-
-        if (currentPasswordHandle != null) {
-            VerifyHandle handle = new VerifyHandle(currentPasswordHandle);
-            if (Arrays.equals(currentPassword, handle.password)) {
-                // Trusted enroll
-                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
-                refreshSid(uid, handle.sid, false);
-                handleMap.put(uid, newHandle.toBytes());
-                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-            } else {
-                return null;
-            }
-        } else {
-            // Untrusted enroll
-            long newSid = new Random().nextLong();
-            VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
-            refreshSid(uid, newSid, true);
-            handleMap.put(uid, newHandle.toBytes());
-            return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
-        }
-    }
-
-    @Override
-    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
-            byte[] providedPassword) throws android.os.RemoteException {
-        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
-    }
-
-    @Override
-    public GateKeeperResponse verifyChallenge(int uid, long challenge,
-            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
-
-        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
-        if (Arrays.equals(handle.password, providedPassword)) {
-            byte[] knownHandle = handleMap.get(uid);
-            if (knownHandle != null) {
-                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
-                    throw new AssertionFailedError("Got correct but obsolete handle");
-                }
-            }
-            refreshSid(uid, handle.sid, false);
-            AuthToken token = new AuthToken(challenge, handle.sid);
-            refreshAuthToken(uid, token);
-            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
-        } else {
-            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
-        }
-    }
-
-    private void refreshAuthToken(int uid, AuthToken token) {
-        authTokenMap.put(uid, token);
-    }
-
-    public AuthToken getAuthToken(int uid) {
-        return authTokenMap.get(uid);
-    }
-
-    public AuthToken getAuthTokenForSid(long sid) {
-        for(AuthToken token : authTokenMap.values()) {
-            if (token.sid == sid) {
-                return token;
-            }
-        }
-        return null;
-    }
-
-    public void clearAuthToken(int uid) {
-        authTokenMap.remove(uid);
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearSecureUserId(int userId) throws RemoteException {
-        sidMap.remove(userId);
-    }
-
-    @Override
-    public long getSecureUserId(int userId) throws RemoteException {
-        if (sidMap.containsKey(userId)) {
-            return sidMap.get(userId);
-        } else {
-            return 0L;
-        }
-    }
-
-    private void refreshSid(int uid, long sid, boolean force) {
-        if (!sidMap.containsKey(uid) || force) {
-            sidMap.put(uid, sid);
-        } else{
-            if (sidMap.get(uid) != sid) {
-                throw new AssertionFailedError("Inconsistent SID");
-            }
-        }
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
deleted file mode 100644
index 8bceed4..0000000
--- a/services/tests/servicestests/src/com/android/server/MockLockSettingsContext.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import android.app.NotificationManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.os.UserManager;
-
-public class MockLockSettingsContext extends ContextWrapper {
-
-    private UserManager mUserManager;
-    private NotificationManager mNotificationManager;
-    private DevicePolicyManager mDevicePolicyManager;
-
-    public MockLockSettingsContext(Context base, UserManager userManager,
-            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager) {
-        super(base);
-        mUserManager = userManager;
-        mNotificationManager = notificationManager;
-        mDevicePolicyManager = devicePolicyManager;
-    }
-
-    @Override
-    public Object getSystemService(String name) {
-        if (USER_SERVICE.equals(name)) {
-            return mUserManager;
-        } else if (NOTIFICATION_SERVICE.equals(name)) {
-            return mNotificationManager;
-        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
-            return mDevicePolicyManager;
-        } else {
-            throw new RuntimeException("System service not mocked: " + name);
-        }
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String permission, String message) {
-        // Skip permission checks for unit tests.
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/MockStorageManager.java
deleted file mode 100644
index 17c8ec2..0000000
--- a/services/tests/servicestests/src/com/android/server/MockStorageManager.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import android.content.pm.IPackageMoveObserver;
-import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.storage.DiskInfo;
-import android.os.storage.IObbActionListener;
-import android.os.storage.IStorageEventListener;
-import android.os.storage.IStorageManager;
-import android.os.storage.IStorageShutdownObserver;
-import android.os.storage.StorageVolume;
-import android.os.storage.VolumeInfo;
-import android.os.storage.VolumeRecord;
-import android.util.ArrayMap;
-import android.util.Pair;
-
-import com.android.internal.os.AppFuseMount;
-
-import junit.framework.AssertionFailedError;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class MockStorageManager implements IStorageManager {
-
-    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
-    private boolean mIgnoreBadUnlock;
-
-    @Override
-    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        getUserAuth(userId).add(new Pair<>(token, secret));
-    }
-
-    @Override
-    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
-        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
-        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
-        auths.clear();
-        auths.add(latest);
-    }
-
-    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
-        if (!mAuth.containsKey(userId)) {
-            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
-            auths.add(new Pair(null, null));
-            mAuth.put(userId,  auths);
-        }
-        return mAuth.get(userId);
-    }
-
-    public byte[] getUserUnlockToken(int userId) {
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (auths.size() != 1) {
-            throw new AssertionFailedError("More than one secret exists");
-        }
-        return auths.get(0).second;
-    }
-
-    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
-            throws RemoteException {
-        listener.onStarted(userId, null);
-        listener.onFinished(userId, null);
-        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
-        if (secret != null) {
-            if (auths.size() > 1) {
-                throw new AssertionFailedError("More than one secret exists");
-            }
-            Pair<byte[], byte[]> auth = auths.get(0);
-            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
-                throw new AssertionFailedError("Invalid secret to unlock user");
-            }
-        } else {
-            if (auths != null && auths.size() > 0) {
-                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
-            }
-        }
-    }
-
-    public void setIgnoreBadUnlock(boolean ignore) {
-        mIgnoreBadUnlock = ignore;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void registerListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageConnected() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUsbMassStorageEnabled() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public int formatVolume(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int[] getStorageUsers(String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getVolumeState(String mountPoint) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
-            boolean external) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int finalizeSecureContainer(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int destroySecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isSecureContainerMounted(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerPath(String id) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String[] getSecureContainerList() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void finishMediaUpdate() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
-            int nonce) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isObbMounted(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getMountedObbPath(String rawPath) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isExternalStorageEmulated() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int decryptStorage(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int encryptStorage(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int changeEncryptionPassword(int type, String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getEncryptionState() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int verifyEncryptionPassword(String password) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int fixPermissionsSecureContainer(String id, int gid, String filename)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int mkdirs(String callingPkg, String path) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getPasswordType() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clearPassword() throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public void setField(String field, String contents) throws RemoteException {
-        throw new UnsupportedOperationException();
-
-    }
-
-    @Override
-    public String getField(String field) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long lastMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void runMaintenance() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void waitForAsecScan() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DiskInfo[] getDisks() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void mount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unmount(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void format(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPublic(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionPrivate(String diskId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void partitionMixed(String diskId, int ratio) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetVolume(String fsUuid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void forgetAllVolumes() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPrimaryStorageUuid() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long benchmark(String volId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setDebugFlags(int flags, int mask) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void lockUserKey(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroyUserStorage(String volumeUuid, int userId, int flags)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isConvertibleToFBE() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void fstrim(int flags) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
-            throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getAllocatableBytes(String path, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void allocateBytes(String path, long bytes, int flags) {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
deleted file mode 100644
index 9389e48..0000000
--- a/services/tests/servicestests/src/com/android/server/MockSyntheticPasswordManager.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server;
-
-import android.hardware.weaver.V1_0.IWeaver;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-
-import junit.framework.AssertionFailedError;
-
-import java.nio.ByteBuffer;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
-public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
-
-    private MockGateKeeperService mGateKeeper;
-    private IWeaver mWeaverService;
-
-    public MockSyntheticPasswordManager(LockSettingsStorage storage,
-            MockGateKeeperService gatekeeper) {
-        super(storage);
-        mGateKeeper = gatekeeper;
-    }
-
-    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
-
-    @Override
-    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
-        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
-            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
-        buffer.put(blob, 0, blob.length);
-        buffer.flip();
-        int len;
-        len = buffer.getInt();
-        byte[] data = new byte[len];
-        buffer.get(data);
-        len = buffer.getInt();
-        byte[] appId = new byte[len];
-        buffer.get(appId);
-        long sid = buffer.getLong();
-        if (!Arrays.equals(appId, applicationId)) {
-            throw new AssertionFailedError("Invalid application id");
-        }
-        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
-            throw new AssertionFailedError("No valid auth token");
-        }
-        return data;
-    }
-
-    @Override
-    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
-        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
-                + applicationId.length + Long.BYTES);
-        buffer.putInt(data.length);
-        buffer.put(data);
-        buffer.putInt(applicationId.length);
-        buffer.put(applicationId);
-        buffer.putLong(sid);
-        byte[] result = buffer.array();
-        mBlobs.put(blobKeyName, result);
-        return result;
-    }
-
-    @Override
-    protected void destroySPBlobKey(String keyAlias) {
-    }
-
-    @Override
-    protected long sidFromPasswordHandle(byte[] handle) {
-        return new MockGateKeeperService.VerifyHandle(handle).sid;
-    }
-
-    @Override
-    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
-        try {
-            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
-            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
-            return f.generateSecret(spec).getEncoded();
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    @Override
-    protected IWeaver getWeaverService() throws RemoteException {
-        return mWeaverService;
-    }
-
-    public void enableWeaver() {
-        mWeaverService = new MockWeaverService();
-        initWeaverService();
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockWeaverService.java b/services/tests/servicestests/src/com/android/server/MockWeaverService.java
deleted file mode 100644
index 0de50ab..0000000
--- a/services/tests/servicestests/src/com/android/server/MockWeaverService.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.android.server;
-
-import android.hardware.weaver.V1_0.IWeaver;
-import android.hardware.weaver.V1_0.WeaverConfig;
-import android.hardware.weaver.V1_0.WeaverReadResponse;
-import android.hardware.weaver.V1_0.WeaverStatus;
-import android.hidl.base.V1_0.DebugInfo;
-import android.os.IHwBinder;
-import android.os.IHwBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.util.Pair;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class MockWeaverService implements IWeaver {
-
-    private static final int MAX_SLOTS = 8;
-    private static final int KEY_LENGTH = 256 / 8;
-    private static final int VALUE_LENGTH = 256 / 8;
-
-    private Pair<ArrayList<Byte>, ArrayList<Byte>>[] slots = new Pair[MAX_SLOTS];
-    @Override
-    public void getConfig(getConfigCallback cb) throws RemoteException {
-        WeaverConfig config = new WeaverConfig();
-        config.keySize = KEY_LENGTH;
-        config.valueSize = VALUE_LENGTH;
-        config.slots = MAX_SLOTS;
-        cb.onValues(WeaverStatus.OK, config);
-    }
-
-    @Override
-    public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
-            throws RemoteException {
-        if (slotId < 0 || slotId >= MAX_SLOTS) {
-            throw new RuntimeException("Invalid slot id");
-        }
-        slots[slotId] = Pair.create((ArrayList<Byte>) key.clone(), (ArrayList<Byte>) value.clone());
-        return WeaverStatus.OK;
-    }
-
-    @Override
-    public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
-        if (slotId < 0 || slotId >= MAX_SLOTS) {
-            throw new RuntimeException("Invalid slot id");
-        }
-
-        WeaverReadResponse response = new WeaverReadResponse();
-        if (key.equals(slots[slotId].first)) {
-            response.value.addAll(slots[slotId].second);
-            cb.onValues(WeaverStatus.OK, response);
-        } else {
-            cb.onValues(WeaverStatus.FAILED, response);
-        }
-    }
-
-    @Override
-    public IHwBinder asBinder() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArrayList<String> interfaceChain() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String interfaceDescriptor() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setHALInstrumentation() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean linkToDeath(DeathRecipient recipient, long cookie) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void ping() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DebugInfo getDebugInfo() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void notifySyspropsChanged() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean unlinkToDeath(DeathRecipient recipient) throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArrayList<byte[]> getHashChain() throws RemoteException {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java
index 9a9c243..58a4456 100644
--- a/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java
@@ -16,10 +16,12 @@
 
 package com.android.server;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
@@ -32,6 +34,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.display.DisplayTransformManager;
 import com.android.server.display.NightDisplayService;
+import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
 import org.junit.After;
@@ -41,6 +44,10 @@
 import org.mockito.Mockito;
 
 import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 import static org.mockito.Mockito.doReturn;
@@ -51,7 +58,7 @@
     private Context mContext;
     private int mUserId;
 
-    private TwilightManager mTwilightManager;
+    private MockTwilightManager mTwilightManager;
 
     private NightDisplayController mNightDisplayController;
     private NightDisplayService mNightDisplayService;
@@ -73,7 +80,7 @@
         final DisplayTransformManager dtm = Mockito.mock(DisplayTransformManager.class);
         LocalServices.addService(DisplayTransformManager.class, dtm);
 
-        mTwilightManager = Mockito.mock(TwilightManager.class);
+        mTwilightManager = new MockTwilightManager();
         LocalServices.addService(TwilightManager.class, mTwilightManager);
 
         mNightDisplayController = new NightDisplayController(mContext, mUserId);
@@ -526,23 +533,371 @@
         assertActivated(true /* activated */);
     }
 
-    /**
-     * Convenience for making a {@link LocalTime} instance with an offset relative to now.
-     *
-     * @param offsetMinutes the offset relative to now (in minutes)
-     * @return the LocalTime instance
-     */
-    private LocalTime getLocalTimeRelativeToNow(int offsetMinutes) {
-        final Calendar c = Calendar.getInstance();
-        c.add(Calendar.MINUTE, offsetMinutes);
-        return new LocalTime(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE));
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOffAfterNight_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOffBeforeNight_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOffDuringNight_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOffInFuture_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOnAfterNight_turnsOn() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOnBeforeNight_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOnDuringNight_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedAfterNight_ifOnInFuture_turnsOff() {
+        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOffAfterNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOffBeforeNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOffDuringNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOffInPast_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOnAfterNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOnBeforeNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOnDuringNight_turnsOff() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedBeforeNight_ifOnInPast_turnsOn() {
+        setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOffAfterNight_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOffBeforeNight_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInFuture_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInPast_turnsOff() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(false /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(false /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOnAfterNight_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOnBeforeNight_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInFuture_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
+    }
+
+    @Test
+    public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInPast_turnsOn() {
+        setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+        final TwilightState state = mTwilightManager.getLastTwilightState();
+        mTwilightManager.setTwilightState(null);
+
+        startService();
+        assertActivated(true /* activated */);
+
+        mTwilightManager.setTwilightState(state);
+        assertActivated(true /* activated */);
     }
 
     /**
      * Configures Night display to use a custom schedule.
      *
      * @param startTimeOffset the offset relative to now to activate Night display (in minutes)
-     * @param endTimeOffset   the offset relative to now to deactivate Night display (in minutes)
+     * @param endTimeOffset the offset relative to now to deactivate Night display (in minutes)
      */
     private void setAutoModeCustom(int startTimeOffset, int endTimeOffset) {
         mNightDisplayController.setAutoMode(NightDisplayController.AUTO_MODE_CUSTOM);
@@ -553,34 +908,21 @@
     /**
      * Configures Night display to use the twilight schedule.
      *
-     * @param sunsetOffset  the offset relative to now for sunset (in minutes)
+     * @param sunsetOffset the offset relative to now for sunset (in minutes)
      * @param sunriseOffset the offset relative to now for sunrise (in minutes)
      */
     private void setAutoModeTwilight(int sunsetOffset, int sunriseOffset) {
         mNightDisplayController.setAutoMode(NightDisplayController.AUTO_MODE_TWILIGHT);
-
-        final LocalTime sunset = getLocalTimeRelativeToNow(sunsetOffset);
-        final LocalTime sunrise = getLocalTimeRelativeToNow(sunriseOffset);
-
-        final Calendar now = Calendar.getInstance();
-        long sunsetMillis = sunset.getDateTimeBefore(now).getTimeInMillis();
-        long sunriseMillis = sunrise.getDateTimeBefore(now).getTimeInMillis();
-        if (sunsetMillis < sunriseMillis) {
-            sunsetMillis = sunset.getDateTimeAfter(now).getTimeInMillis();
-        } else {
-            sunriseMillis = sunrise.getDateTimeAfter(now).getTimeInMillis();
-        }
-
-        final TwilightState state = new TwilightState(sunriseMillis, sunsetMillis);
-        doReturn(state).when(mTwilightManager).getLastTwilightState();
+        mTwilightManager.setTwilightState(
+                getTwilightStateRelativeToNow(sunsetOffset, sunriseOffset));
     }
 
     /**
      * Configures the Night display activated state.
      *
-     * @param activated               {@code true} if Night display should be activated
+     * @param activated {@code true} if Night display should be activated
      * @param lastActivatedTimeOffset the offset relative to now to record that Night display was
-                                      activated (in minutes)
+     * activated (in minutes)
      */
     private void setActivated(boolean activated, int lastActivatedTimeOffset) {
         mNightDisplayController.setActivated(activated);
@@ -617,4 +959,93 @@
                 .that(mNightDisplayController.isActivated())
                 .isEqualTo(activated);
     }
+
+    /**
+     * Convenience for making a {@link LocalTime} instance with an offset relative to now.
+     *
+     * @param offsetMinutes the offset relative to now (in minutes)
+     * @return the LocalTime instance
+     */
+    private static LocalTime getLocalTimeRelativeToNow(int offsetMinutes) {
+        final Calendar c = Calendar.getInstance();
+        c.add(Calendar.MINUTE, offsetMinutes);
+        return new LocalTime(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE));
+    }
+
+    /**
+     * Convenience for making a {@link TwilightState} instance with sunrise/sunset relative to now.
+     *
+     * @param sunsetOffset the offset relative to now for sunset (in minutes)
+     * @param sunriseOffset the offset relative to now for sunrise (in minutes)
+     * @return the TwilightState instance
+     */
+    private static TwilightState getTwilightStateRelativeToNow(int sunsetOffset,
+            int sunriseOffset) {
+        final LocalTime sunset = getLocalTimeRelativeToNow(sunsetOffset);
+        final LocalTime sunrise = getLocalTimeRelativeToNow(sunriseOffset);
+
+        final Calendar now = Calendar.getInstance();
+        long sunsetMillis = sunset.getDateTimeBefore(now).getTimeInMillis();
+        long sunriseMillis = sunrise.getDateTimeBefore(now).getTimeInMillis();
+        if (sunsetMillis < sunriseMillis) {
+            sunsetMillis = sunset.getDateTimeAfter(now).getTimeInMillis();
+        } else {
+            sunriseMillis = sunrise.getDateTimeAfter(now).getTimeInMillis();
+        }
+
+        return new TwilightState(sunriseMillis, sunsetMillis);
+    }
+
+    private static class MockTwilightManager implements TwilightManager {
+
+        private final Map<TwilightListener, Handler> mListeners = new HashMap<>();
+        private TwilightState mTwilightState;
+
+        /**
+         * Updates the TwilightState and notifies any registered listeners.
+         *
+         * @param state the new TwilightState to use
+         */
+        void setTwilightState(TwilightState state) {
+            synchronized (mListeners) {
+                mTwilightState = state;
+
+                final CountDownLatch latch = new CountDownLatch(mListeners.size());
+                for (Map.Entry<TwilightListener, Handler> entry : mListeners.entrySet()) {
+                    entry.getValue().post(new Runnable() {
+                        @Override
+                        public void run() {
+                            entry.getKey().onTwilightStateChanged(state);
+                            latch.countDown();
+                        }
+                    });
+                }
+
+                try {
+                    latch.await(5, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        @Override
+        public void registerListener(@NonNull TwilightListener listener, @NonNull Handler handler) {
+            synchronized (mListeners) {
+                mListeners.put(listener, handler);
+            }
+        }
+
+        @Override
+        public void unregisterListener(@NonNull TwilightListener listener) {
+            synchronized (mListeners) {
+                mListeners.remove(listener);
+            }
+        }
+
+        @Override
+        public TwilightState getLastTwilightState() {
+            return mTwilightState;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
deleted file mode 100644
index 3ec71e4..0000000
--- a/services/tests/servicestests/src/com/android/server/SyntheticPasswordTests.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server;
-
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
-import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
-
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.VerifyCredentialResponse;
-import com.android.server.SyntheticPasswordManager.AuthenticationResult;
-import com.android.server.SyntheticPasswordManager.AuthenticationToken;
-
-
-/**
- * runtest frameworks-services -c com.android.server.SyntheticPasswordTests
- */
-public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testPasswordBasedSyntheticPassword() throws RemoteException {
-        final int USER_ID = 10;
-        final String PASSWORD = "user-password";
-        final String BADPASSWORD = "bad-password";
-        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
-        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
-                null, USER_ID);
-        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
-                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, USER_ID);
-
-        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
-        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
-
-        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
-        assertNull(result.authToken);
-    }
-
-    private void disableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
-    }
-
-    private void enableSyntheticPassword(int userId) throws RemoteException {
-        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
-    }
-
-    private boolean hasSyntheticPassword(int userId) throws RemoteException {
-        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
-    }
-
-    public void testPasswordMigration() throws RemoteException {
-        final String PASSWORD = "testPasswordMigration-password";
-
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        // Performs migration
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-
-        // SP-based verification
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
-        enableSyntheticPassword(userId);
-        mService.setLockCredential(password, password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE, null, userId);
-    }
-
-    public void testSyntheticPasswordChangeCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
-        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
-                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-    public void testSyntheticPasswordClearCredential() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // clear password
-        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // set a new password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-    }
-
-    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
-        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
-        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
-
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        // Untrusted change password
-        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-
-        // Verify the password
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-    }
-
-
-    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
-        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
-        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
-        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
-        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
-        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, MANAGED_PROFILE_USER_ID);
-        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
-        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
-        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
-        assertTrue(primarySid != 0);
-        assertTrue(profileSid != 0);
-        assertTrue(profileSid != primarySid);
-
-        // do migration
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-
-        // verify
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
-        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
-        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
-    }
-
-    public void testTokenBasedResetPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedClearPassword() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
-        final String PASSWORD = "password";
-        final String PATTERN = "123654";
-        final String NEWPASSWORD = "password";
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
-        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-
-        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD, PRIMARY_USER_ID);
-
-        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
-
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
-        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        enableSyntheticPassword(PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
-        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
-    }
-
-    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
-        final String TOKEN = "some-high-entropy-secure-token";
-        final String PASSWORD = "password";
-        // Set up pre-SP user password
-        disableSyntheticPassword(PRIMARY_USER_ID);
-        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PRIMARY_USER_ID);
-        enableSyntheticPassword(PRIMARY_USER_ID);
-
-        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
-        // Token not activated immediately since user password exists
-        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-        // Activate token (password gets migrated to SP at the same time)
-        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
-                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
-                        PRIMARY_USER_ID).getResponseCode());
-        // Verify token is activated
-        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
-    }
-
-    // b/34600579
-    //TODO: add non-migration work profile case, and unify/un-unify transition.
-    //TODO: test token after user resets password
-    //TODO: test token based reset after unified work challenge
-    //TODO: test clear password after unified work challenge
-}
-
diff --git a/services/tests/servicestests/src/com/android/server/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/WeaverBasedSyntheticPasswordTests.java
deleted file mode 100644
index d85a815..0000000
--- a/services/tests/servicestests/src/com/android/server/WeaverBasedSyntheticPasswordTests.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.android.server;
-
-public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mSpManager.enableWeaver();
-    }
-
-}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
index ace65a6..02f645a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityCacheTest.java
@@ -54,6 +54,7 @@
     private static int OTHER_VIEW_ID = 0xCAB2;
     private static int PARENT_VIEW_ID = 0xFED4;
     private static int CHILD_VIEW_ID = 0xFEED;
+    private static int OTHER_CHILD_VIEW_ID = 0xACE2;
     private static int MOCK_CONNECTION_ID = 1;
 
     AccessibilityCache mAccessibilityCache;
@@ -482,6 +483,30 @@
     }
 
     @Test
+    public void addNode_whenNodeBeingReplacedIsOwnGrandparent_doesntCrash() {
+        AccessibilityNodeInfo parentNodeInfo =
+                getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1);
+        parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(CHILD_VIEW_ID, WINDOW_ID_1));
+        parentNodeInfo.addChild(getMockViewWithA11yAndWindowIds(OTHER_CHILD_VIEW_ID, WINDOW_ID_1));
+        AccessibilityNodeInfo childNodeInfo =
+                getNodeWithA11yAndWindowId(CHILD_VIEW_ID, WINDOW_ID_1);
+        childNodeInfo.setParent(getMockViewWithA11yAndWindowIds(PARENT_VIEW_ID, WINDOW_ID_1));
+        childNodeInfo.addChild(getMockViewWithA11yAndWindowIds(PARENT_VIEW_ID, WINDOW_ID_1));
+
+        AccessibilityNodeInfo replacementParentNodeInfo =
+                getNodeWithA11yAndWindowId(PARENT_VIEW_ID, WINDOW_ID_1);
+        try {
+            mAccessibilityCache.add(parentNodeInfo);
+            mAccessibilityCache.add(childNodeInfo);
+            mAccessibilityCache.add(replacementParentNodeInfo);
+        } finally {
+            parentNodeInfo.recycle();
+            childNodeInfo.recycle();
+            replacementParentNodeInfo.recycle();
+        }
+    }
+
+    @Test
     public void testCacheCriticalEventList_doesntLackEvents() {
         for (int i = 0; i < 32; i++) {
             int eventType = 1 << i;
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
new file mode 100644
index 0000000..05f4c13
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/PerformAdbRestoreTaskTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.restore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class PerformAdbRestoreTaskTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void parseBackupFileAndReturnTarStream_backupNotEncrypted_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordProvided_returnsNonNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+
+        assertThat(tarInputStream).isNotNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndPasswordNotProvided_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+
+        assertThat(tarInputStream).isNull();
+    }
+
+    @Test
+    public void
+    parseBackupFileAndReturnTarStream_backupEncryptedAndIncorrectPassword_returnsNull()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "1234");
+
+        assertThat(tarInputStream).isNull();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
new file mode 100644
index 0000000..f124df9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java
@@ -0,0 +1,1002 @@
+package com.android.server.backup.testutils;
+
+import android.app.PackageInstallObserver;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ChangedPackages;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageInstallObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+
+import java.util.List;
+
+/**
+ * Stub for PackageManager to use in tests.
+ */
+public class PackageManagerStub extends PackageManager {
+    public static PackageInfo sPackageInfo;
+
+    @Override
+    public PackageInfo getPackageInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        if (sPackageInfo == null) {
+            throw new NameNotFoundException();
+        }
+
+        return sPackageInfo;
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        return new String[0];
+    }
+
+    @Override
+    public Intent getLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
+        return null;
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName) throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName, int flags)
+            throws NameNotFoundException {
+        return new int[0];
+    }
+
+    @Override
+    public int getPackageUid(String packageName, int flags)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int getPackageUidAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public boolean isPermissionReviewModeEnabled() {
+        return false;
+    }
+
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getActivityInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ServiceInfo getServiceInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo getProviderInfo(ComponentName component, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public int checkPermission(String permName, String pkgName) {
+        return 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
+        return false;
+    }
+
+    @Override
+    public String getPermissionControllerPackageName() {
+        return null;
+    }
+
+    @Override
+    public boolean addPermission(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public boolean addPermissionAsync(PermissionInfo info) {
+        return false;
+    }
+
+    @Override
+    public void removePermission(String name) {
+
+    }
+
+    @Override
+    public void grantRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public void revokeRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+
+    }
+
+    @Override
+    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
+            int flagValues, UserHandle user) {
+
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        return false;
+    }
+
+    @Override
+    public int checkSignatures(String pkg1, String pkg2) {
+        return 0;
+    }
+
+    @Override
+    public int checkSignatures(int uid1, int uid2) {
+        return 0;
+    }
+
+    @Override
+    public String[] getPackagesForUid(int uid) {
+        return new String[0];
+    }
+
+    @Override
+    public String getNameForUid(int uid) {
+        return null;
+    }
+
+    @Override
+    public int getUidForSharedUser(String sharedUserName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplications(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<InstantAppInfo> getInstantApps() {
+        return null;
+    }
+
+    @Override
+    public Drawable getInstantAppIcon(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isInstantApp() {
+        return false;
+    }
+
+    @Override
+    public boolean isInstantApp(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxBytes() {
+        return 0;
+    }
+
+    @Override
+    public int getInstantAppCookieMaxSize() {
+        return 0;
+    }
+
+    @Override
+    public byte[] getInstantAppCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public void clearInstantAppCookie() {
+
+    }
+
+    @Override
+    public void updateInstantAppCookie(byte[] cookie) {
+
+    }
+
+    @Override
+    public boolean setInstantAppCookie(byte[] cookie) {
+        return false;
+    }
+
+    @Override
+    public String[] getSystemSharedLibraryNames() {
+        return new String[0];
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibraries(int flags) {
+        return null;
+    }
+
+    @Override
+    public List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public String getServicesSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public String getSharedSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
+    public ChangedPackages getChangedPackages(int sequenceNumber) {
+        return null;
+    }
+
+    @Override
+    public FeatureInfo[] getSystemAvailableFeatures() {
+        return new FeatureInfo[0];
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name) {
+        return false;
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
+        return false;
+    }
+
+    @Override
+    public ResolveInfo resolveActivity(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
+            Intent[] specifics,
+            Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public ResolveInfo resolveService(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
+            int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProvider(String name, int flags) {
+        return null;
+    }
+
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
+        return null;
+    }
+
+    @Override
+    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
+        return null;
+    }
+
+    @Override
+    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
+        return null;
+    }
+
+    @Override
+    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getDefaultActivityIcon() {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationIcon(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Drawable getApplicationLogo(String packageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
+            Rect badgeLocation, int badgeDensity) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public CharSequence getApplicationLabel(ApplicationInfo info) {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForActivity(ComponentName activityName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(ApplicationInfo app)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplication(String appPackageName)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
+            throws NameNotFoundException {
+        return null;
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
+            String installerPackageName) {
+
+    }
+
+    @Override
+    public int installExistingPackage(String packageName)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        return 0;
+    }
+
+    @Override
+    public void verifyPendingInstall(int id, int verificationCode) {
+
+    }
+
+    @Override
+    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+            long millisecondsToDelay) {
+
+    }
+
+    @Override
+    public void verifyIntentFilter(int verificationId, int verificationCode,
+            List<String> failedDomains) {
+
+    }
+
+    @Override
+    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
+        return 0;
+    }
+
+    @Override
+    public boolean updateIntentVerificationStatusAsUser(String packageName, int status,
+            int userId) {
+        return false;
+    }
+
+    @Override
+    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
+        return null;
+    }
+
+    @Override
+    public List<IntentFilter> getAllIntentFilters(String packageName) {
+        return null;
+    }
+
+    @Override
+    public String getDefaultBrowserPackageNameAsUser(int userId) {
+        return null;
+    }
+
+    @Override
+    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
+
+    }
+
+    @Override
+    public void setUpdateAvailable(String packageName, boolean updateAvaialble) {
+
+    }
+
+    @Override
+    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
+
+    }
+
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
+            int flags,
+            int userId) {
+
+    }
+
+    @Override
+    public String getInstallerPackageName(String packageName) {
+        return null;
+    }
+
+    @Override
+    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
+            IPackageDataObserver observer) {
+
+    }
+
+    @Override
+    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
+
+    }
+
+    @Override
+    public void getPackageSizeInfoAsUser(String packageName, int userId,
+            IPackageStatsObserver observer) {
+
+    }
+
+    @Override
+    public void addPackageToPreferred(String packageName) {
+
+    }
+
+    @Override
+    public void removePackageFromPreferred(String packageName) {
+
+    }
+
+    @Override
+    public List<PackageInfo> getPreferredPackages(int flags) {
+        return null;
+    }
+
+    @Override
+    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
+            ComponentName activity) {
+
+    }
+
+    @Override
+    public void clearPackagePreferredActivities(String packageName) {
+
+    }
+
+    @Override
+    public int getPreferredActivities(List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
+        return 0;
+    }
+
+    @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        return null;
+    }
+
+    @Override
+    public void setComponentEnabledSetting(ComponentName componentName, int newState,
+            int flags) {
+
+    }
+
+    @Override
+    public int getComponentEnabledSetting(ComponentName componentName) {
+        return 0;
+    }
+
+    @Override
+    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+
+    }
+
+    @Override
+    public int getApplicationEnabledSetting(String packageName) {
+        return 0;
+    }
+
+    @Override
+    public void flushPackageRestrictionsAsUser(int userId) {
+
+    }
+
+    @Override
+    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean getApplicationHiddenSettingAsUser(String packageName,
+            UserHandle userHandle) {
+        return false;
+    }
+
+    @Override
+    public boolean isSafeMode() {
+        return false;
+    }
+
+    @Override
+    public void addOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public void removeOnPermissionsChangeListener(
+            OnPermissionsChangedListener listener) {
+
+    }
+
+    @Override
+    public KeySet getKeySetByAlias(String packageName, String alias) {
+        return null;
+    }
+
+    @Override
+    public KeySet getSigningKeySet(String packageName) {
+        return null;
+    }
+
+    @Override
+    public boolean isSignedBy(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public boolean isSignedByExactly(String packageName, KeySet ks) {
+        return false;
+    }
+
+    @Override
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
+        return new String[0];
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        return false;
+    }
+
+    @Override
+    public void setApplicationCategoryHint(String packageName, int categoryHint) {
+
+    }
+
+    @Override
+    public int getMoveStatus(int moveId) {
+        return 0;
+    }
+
+    @Override
+    public void registerMoveCallback(MoveCallback callback, Handler handler) {
+
+    }
+
+    @Override
+    public void unregisterMoveCallback(MoveCallback callback) {
+
+    }
+
+    @Override
+    public int movePackage(String packageName, VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
+        return null;
+    }
+
+    @Override
+    public int movePrimaryStorage(VolumeInfo vol) {
+        return 0;
+    }
+
+    @Override
+    public VolumeInfo getPrimaryStorageCurrentVolume() {
+        return null;
+    }
+
+    @Override
+    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
+        return null;
+    }
+
+    @Override
+    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
+        return null;
+    }
+
+    @Override
+    public boolean isUpgrade() {
+        return false;
+    }
+
+    @Override
+    public PackageInstaller getPackageInstaller() {
+        return null;
+    }
+
+    @Override
+    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
+            int targetUserId,
+            int flags) {
+
+    }
+
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+
+    }
+
+    @Override
+    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        return null;
+    }
+
+    @Override
+    public boolean isPackageAvailable(String packageName) {
+        return false;
+    }
+
+    @Override
+    public int getInstallReason(String packageName, UserHandle user) {
+        return 0;
+    }
+
+    @Override
+    public boolean canRequestPackageInstalls() {
+        return false;
+    }
+
+    @Override
+    public ComponentName getInstantAppResolverSettingsComponent() {
+        return null;
+    }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return null;
+    }
+
+    @Override
+    public String getInstantAppAndroidId(String packageName, UserHandle user) {
+        return null;
+    }
+
+    @Override
+    public void registerDexModule(String dexModulePath,
+            DexModuleRegisterCallback callback) {
+
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
new file mode 100644
index 0000000..8784dd5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.utils;
+
+import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
+import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.internal.verification.VerificationModeFactory.times;
+
+import android.app.backup.IBackupManagerMonitor;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.Signature;
+import android.os.Bundle;
+import android.os.Process;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.servicestests.R;
+import com.android.server.backup.FileMetadata;
+import com.android.server.backup.restore.PerformAdbRestoreTask;
+import com.android.server.backup.restore.RestorePolicy;
+import com.android.server.backup.testutils.PackageManagerStub;
+
+import com.google.common.hash.Hashing;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.InputStream;
+import java.util.List;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class TarBackupReaderTest {
+    private static final String TELEPHONY_PACKAGE_NAME = "com.android.providers.telephony";
+    private static final String TELEPHONY_PACKAGE_SIGNATURE_SHA256 =
+            "301aa3cb081134501c45f1422abc66c24224fd5ded5fdc8f17e697176fd866aa";
+    private static final int TELEPHONY_PACKAGE_VERSION = 25;
+    private static final Signature FAKE_SIGNATURE_1 = new Signature("1234");
+    private static final Signature FAKE_SIGNATURE_2 = new Signature("5678");
+
+    @Mock private BytesReadListener mBytesReadListenerMock;
+    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
+
+    private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    @Test
+    public void readTarHeaders_backupEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readTarHeaders_backupNotEncrypted_correctlyParsesFileMetadata() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        assertThat(fileMetadata.packageName).isEqualTo(TELEPHONY_PACKAGE_NAME);
+        assertThat(fileMetadata.mode).isEqualTo(0600);
+        assertThat(fileMetadata.size).isEqualTo(2438);
+        assertThat(fileMetadata.domain).isEqualTo(null);
+        assertThat(fileMetadata.path).isEqualTo("_manifest");
+    }
+
+    @Test
+    public void readAppManifest_backupEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_with_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, "123");
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void readAppManifest_backupNotEncrypted_correctlyParsesAppManifest() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata fileMetadata = tarBackupReader.readTarHeaders();
+
+        Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures(fileMetadata);
+
+        assertThat(fileMetadata.version).isEqualTo(TELEPHONY_PACKAGE_VERSION);
+        assertThat(fileMetadata.hasApk).isFalse();
+        assertThat(signatures).isNotNull();
+        assertThat(signatures).hasLength(1);
+
+        String signatureSha256 = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
+        assertThat(signatureSha256).isEqualTo(TELEPHONY_PACKAGE_SIGNATURE_SHA256);
+    }
+
+    @Test
+    public void chooseRestorePolicy_signaturesIsNull_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, new FileMetadata(), null /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        verifyZeroInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = true;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_packageDoesNotExistAndAllowApksAndDoesNotHaveApk_returnsAcceptIfApkLogsCannotRestore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        FileMetadata info = new FileMetadata();
+        info.hasApk = false;
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock, times(2)).onEvent(bundleCaptor.capture());
+        List<Bundle> eventBundles = bundleCaptor.getAllValues();
+        assertThat(eventBundles).hasSize(2);
+        assertThat(eventBundles.get(0).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+        assertThat(eventBundles.get(1).get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK);
+    }
+
+    @Test
+    public void chooseRestorePolicy_packageDoesNotExistAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        PackageManagerStub.sPackageInfo = null;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_APK_NOT_INSTALLED);
+    }
+
+    @Test
+    public void chooseRestorePolicy_doesNotAllowsBackup_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_ALLOW_BACKUP;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithNoAgent_returnsIgnore() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_SYSTEM_APP_NO_AGENT);
+    }
+
+    @Test
+    public void chooseRestorePolicy_nonSystemAppSignaturesDoNotMatch_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_2};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH);
+    }
+
+    @Test
+    public void chooseRestorePolicy_systemAppWithBackupAgentAndRestoreAnyVersion_returnsAccept() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.SYSTEM_UID;
+        packageInfo.applicationInfo.backupAgentName = "backup.agent";
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_restoreAnyVersion_returnsAccept() throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |=
+                ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, new FileMetadata(), signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_RESTORE_ANY_VERSION);
+    }
+
+    @Test
+    public void chooseRestorePolicy_notRestoreAnyVersionButVersionMatch_returnsAccept()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 1;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 2;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSIONS_MATCH);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+        info.hasApk = true;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                true /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
+        verifyNoMoreInteractions(mBackupManagerMonitorMock);
+    }
+
+    @Test
+    public void
+    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchAndDoesNotAllowApks_returnsIgnore()
+            throws Exception {
+        InputStream inputStream = mContext.getResources().openRawResource(
+                R.raw.backup_telephony_no_password);
+        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
+                inputStream, null);
+        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
+                mBytesReadListenerMock, mBackupManagerMonitorMock);
+        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
+        FileMetadata info = new FileMetadata();
+        info.version = 2;
+
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+        packageInfo.applicationInfo.backupAgentName = null;
+        packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1};
+        packageInfo.versionCode = 1;
+        PackageManagerStub.sPackageInfo = packageInfo;
+
+        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
+                false /* allowApks */, info, signatures);
+
+        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
+        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
+        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
+                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
+    }
+
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
new file mode 100644
index 0000000..a2b4568
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.IActivityManager;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.pm.UserInfo;
+import android.os.FileUtils;
+import android.os.IProgressListener;
+import android.os.UserManager;
+import android.security.KeyStore;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+
+public class BaseLockSettingsServiceTests extends AndroidTestCase {
+    protected static final int PRIMARY_USER_ID = 0;
+    protected static final int MANAGED_PROFILE_USER_ID = 12;
+    protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
+    protected static final int SECONDARY_USER_ID = 20;
+
+    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
+    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
+            UserInfo.FLAG_INITIALIZED);
+
+    private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
+
+    LockSettingsService mService;
+
+    MockLockSettingsContext mContext;
+    LockSettingsStorageTestable mStorage;
+
+    LockPatternUtils mLockPatternUtils;
+    MockGateKeeperService mGateKeeperService;
+    NotificationManager mNotificationManager;
+    UserManager mUserManager;
+    MockStorageManager mStorageManager;
+    IActivityManager mActivityManager;
+    DevicePolicyManager mDevicePolicyManager;
+    KeyStore mKeyStore;
+    MockSyntheticPasswordManager mSpManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mLockPatternUtils = mock(LockPatternUtils.class);
+        mGateKeeperService = new MockGateKeeperService();
+        mNotificationManager = mock(NotificationManager.class);
+        mUserManager = mock(UserManager.class);
+        mStorageManager = new MockStorageManager();
+        mActivityManager = mock(IActivityManager.class);
+        mDevicePolicyManager = mock(DevicePolicyManager.class);
+
+        mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
+                mDevicePolicyManager);
+        mStorage = new LockSettingsStorageTestable(mContext,
+                new File(getContext().getFilesDir(), "locksettings"));
+        File storageDir = mStorage.mStorageDir;
+        if (storageDir.exists()) {
+            FileUtils.deleteContents(storageDir);
+        } else {
+            storageDir.mkdirs();
+        }
+
+        mSpManager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
+        mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils,
+                mStorage, mGateKeeperService, mKeyStore, mStorageManager, mActivityManager,
+                mSpManager);
+        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
+        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
+        installChildProfile(MANAGED_PROFILE_USER_ID);
+        installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
+        when(mUserManager.getUsers(anyBoolean())).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
+        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
+
+        when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
+                new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                mStorageManager.unlockUser((int)args[0], (byte[])args[2],
+                        (IProgressListener) args[3]);
+                return true;
+            }
+        });
+
+        when(mLockPatternUtils.getLockSettings()).thenReturn(mService);
+
+        // Adding a fake Device Owner app which will enable escrow token support in LSS.
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
+                new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
+    }
+
+    private UserInfo installChildProfile(int profileId) {
+        final UserInfo userInfo = new UserInfo(
+            profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
+        mPrimaryUserProfiles.add(userInfo);
+        when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
+        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
+        return userInfo;
+    }
+
+    private UserInfo installAndTurnOffChildProfile(int profileId) {
+        final UserInfo userInfo = installChildProfile(profileId);
+        userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
+        when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
+        when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
+        return userInfo;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+        File db = getContext().getDatabasePath("locksettings.db");
+        assertTrue(!db.exists() || db.delete());
+
+        File storageDir = mStorage.mStorageDir;
+        assertTrue(FileUtils.deleteContents(storageDir));
+    }
+
+    protected static void assertArrayEquals(byte[] expected, byte[] actual) {
+        assertTrue(Arrays.equals(expected, actual));
+    }
+
+    protected static void assertArrayNotSame(byte[] expected, byte[] actual) {
+        assertFalse(Arrays.equals(expected, actual));
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
new file mode 100644
index 0000000..3a4aa2d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.IActivityManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.storage.IStorageManager;
+import android.security.KeyStore;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.FileNotFoundException;
+
+public class LockSettingsServiceTestable extends LockSettingsService {
+
+    private static class MockInjector extends LockSettingsService.Injector {
+
+        private LockSettingsStorage mLockSettingsStorage;
+        private KeyStore mKeyStore;
+        private IActivityManager mActivityManager;
+        private LockPatternUtils mLockPatternUtils;
+        private IStorageManager mStorageManager;
+        private SyntheticPasswordManager mSpManager;
+
+        public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
+                IActivityManager activityManager, LockPatternUtils lockPatternUtils,
+                IStorageManager storageManager, SyntheticPasswordManager spManager) {
+            super(context);
+            mLockSettingsStorage = storage;
+            mKeyStore = keyStore;
+            mActivityManager = activityManager;
+            mLockPatternUtils = lockPatternUtils;
+            mStorageManager = storageManager;
+            mSpManager = spManager;
+        }
+
+        @Override
+        public Handler getHandler() {
+            return mock(Handler.class);
+        }
+
+        @Override
+        public LockSettingsStorage getStorage() {
+            return mLockSettingsStorage;
+        }
+
+        @Override
+        public LockSettingsStrongAuth getStrongAuth() {
+            return mock(LockSettingsStrongAuth.class);
+        }
+
+        @Override
+        public SynchronizedStrongAuthTracker getStrongAuthTracker() {
+            return mock(SynchronizedStrongAuthTracker.class);
+        }
+
+        @Override
+        public IActivityManager getActivityManager() {
+            return mActivityManager;
+        }
+
+        @Override
+        public LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        public KeyStore getKeyStore() {
+            return mKeyStore;
+        }
+
+        @Override
+        public IStorageManager getStorageManager() {
+            return mStorageManager;
+        }
+
+        @Override
+        public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
+            return mSpManager;
+        }
+
+        @Override
+        public int binderGetCallingUid() {
+            return Process.SYSTEM_UID;
+        }
+
+
+    }
+
+    protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
+            LockSettingsStorage storage, MockGateKeeperService gatekeeper, KeyStore keystore,
+            IStorageManager storageManager, IActivityManager mActivityManager,
+            SyntheticPasswordManager spManager) {
+        super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
+                storageManager, spManager));
+        mGateKeeperService = gatekeeper;
+    }
+
+    @Override
+    protected void tieProfileLockToParent(int userId, String password) {
+        mStorage.writeChildProfileLock(userId, password.getBytes());
+    }
+
+    @Override
+    protected String getDecryptedPasswordForTiedProfile(int userId) throws FileNotFoundException,
+            KeyPermanentlyInvalidatedException {
+        byte[] storedData = mStorage.readChildProfileLock(userId);
+        if (storedData == null) {
+            throw new FileNotFoundException("Child profile lock file not found");
+        }
+        try {
+            if (mGateKeeperService.getSecureUserId(userId) == 0) {
+                throw new KeyPermanentlyInvalidatedException();
+            }
+        } catch (RemoteException e) {
+            // shouldn't happen.
+        }
+        return new String(storedData);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
new file mode 100644
index 0000000..2f0ac38
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+
+import android.os.RemoteException;
+import android.service.gatekeeper.GateKeeperResponse;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import com.android.server.locksettings.MockGateKeeperService.VerifyHandle;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
+ */
+public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testCreatePasswordPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD);
+    }
+
+    public void testCreatePatternPrimaryUser() throws RemoteException {
+        testCreateCredential(PRIMARY_USER_ID, "123456789", CREDENTIAL_TYPE_PATTERN);
+    }
+
+    public void testChangePasswordPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "78963214", CREDENTIAL_TYPE_PATTERN,
+                "asdfghjk", CREDENTIAL_TYPE_PASSWORD);
+    }
+
+    public void testChangePatternPrimaryUser() throws RemoteException {
+        testChangeCredentials(PRIMARY_USER_ID, "!£$%^&*(())", CREDENTIAL_TYPE_PASSWORD,
+                "1596321", CREDENTIAL_TYPE_PATTERN);
+    }
+
+    public void testChangePasswordFailPrimaryUser() throws RemoteException {
+        final long sid = 1234;
+        final String FAILED_MESSAGE = "Failed to enroll password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
+
+        try {
+            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, "badpwd",
+                    PRIMARY_USER_ID);
+            fail("Did not fail when enrolling using incorrect credential");
+        } catch (RemoteException expected) {
+            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
+        }
+        try {
+            mService.setLockCredential("newpwd", CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+            fail("Did not fail when enrolling using incorrect credential");
+        } catch (RemoteException expected) {
+            assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
+        }
+        assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
+    }
+
+    public void testClearPasswordPrimaryUser() throws RemoteException {
+        final String PASSWORD = "password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD, PRIMARY_USER_ID);
+        assertFalse(mService.havePassword(PRIMARY_USER_ID));
+        assertFalse(mService.havePattern(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testManagedProfileUnifiedChallenge() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallenge-pwd";
+        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PRIMARY_USER_ID);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final long turnedOffProfileSid =
+                mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+        assertTrue(turnedOffProfileSid != 0);
+        assertTrue(turnedOffProfileSid != primarySid);
+        assertTrue(turnedOffProfileSid != profileSid);
+
+        // clear auth token and wait for verify challenge from primary user to re-generate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
+        // verify credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+
+        // Verify that we have a new auth token for the profile
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
+        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
+
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        mStorageManager.setIgnoreBadUnlock(true);
+        // Change primary password and verify that profile SID remains
+        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                UnifiedPassword, PRIMARY_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
+
+        // Clear unified challenge
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, UnifiedPassword,
+                PRIMARY_USER_ID);
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallenge() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallenge-primary";
+        final String profilePassword = "testManagedProfileSeparateChallenge-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PRIMARY_USER_ID);
+        /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
+         * credential as part of verifyCredential() before the new credential is committed in
+         * StorageManager. So we relax the check in our mock StorageManager to allow that.
+         */
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                MANAGED_PROFILE_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // clear auth token and make sure verify challenge from primary user does not regenerate it.
+        mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
+        // verify primary credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
+                .getResponseCode());
+        assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+
+        // verify profile credential
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+
+        // Change primary credential and make sure we don't affect profile
+        mStorageManager.setIgnoreBadUnlock(true);
+        mService.setLockCredential("pwd", LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                primaryPassword, PRIMARY_USER_ID);
+        mStorageManager.setIgnoreBadUnlock(false);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
+                profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+    }
+
+    private void testCreateCredential(int userId, String credential, int type)
+            throws RemoteException {
+        mService.setLockCredential(credential, type, null, userId);
+        assertVerifyCredentials(userId, credential, type, -1);
+    }
+
+    private void testChangeCredentials(int userId, String newCredential, int newType,
+            String oldCredential, int oldType) throws RemoteException {
+        final long sid = 1234;
+        initializeStorageWithCredential(userId, oldCredential, oldType, sid);
+        mService.setLockCredential(newCredential, newType, oldCredential, userId);
+        assertVerifyCredentials(userId, newCredential, newType, sid);
+    }
+
+    private void assertVerifyCredentials(int userId, String credential, int type, long sid)
+            throws RemoteException{
+        final long challenge = 54321;
+        VerifyCredentialResponse response = mService.verifyCredential(credential, type, challenge,
+                userId);
+
+        assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
+        if (sid != -1) assertEquals(sid, mGateKeeperService.getSecureUserId(userId));
+        final int incorrectType;
+        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            assertTrue(mService.havePassword(userId));
+            assertFalse(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
+        } else if (type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){
+            assertFalse(mService.havePassword(userId));
+            assertTrue(mService.havePattern(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        } else {
+            assertFalse(mService.havePassword(userId));
+            assertFalse(mService.havePassword(userId));
+            incorrectType = LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+        }
+        // check for bad type
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(credential,
+                incorrectType, challenge, userId).getResponseCode());
+        // check for bad credential
+        assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential("0" + credential,
+                type, challenge, userId).getResponseCode());
+    }
+
+    private void initializeStorageWithCredential(int userId, String credential, int type, long sid) {
+        byte[] oldHash = new VerifyHandle(credential.getBytes(), sid).toBytes();
+        if (type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD) {
+            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                    LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+        } else {
+            mStorage.writeCredentialHash(CredentialHash.create(oldHash,
+                    LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
new file mode 100644
index 0000000..424c08c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import static junit.framework.Assert.*;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static java.io.FileDescriptor.*;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.FileDescriptor;
+
+/**
+ * Test class for {@link LockSettingsShellCommand}.
+ *
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsShellCommandTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class LockSettingsShellCommandTest {
+
+    private LockSettingsShellCommand mCommand;
+
+    private @Mock LockPatternUtils mLockPatternUtils;
+    private int mUserId;
+    private final Binder mBinder = new Binder();
+    private final ShellCallback mShellCallback = new ShellCallback();
+    private final ResultReceiver mResultReceiver = new ResultReceiver(
+            new Handler(Looper.getMainLooper()));
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mUserId = ActivityManager.getCurrentUser();
+        mCommand = new LockSettingsShellCommand(context, mLockPatternUtils);
+    }
+
+    @Test
+    public void testWrongPassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false);
+        assertEquals(-1, mCommand.exec(mBinder, in, out, err,
+                new String[] { "set-pin", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt());
+    }
+
+    @Test
+    public void testChangePin() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pin", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePassword() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true);
+        assertEquals(0,  mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-password", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC,
+                mUserId);
+    }
+
+    @Test
+    public void testChangePattern() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "set-pattern", "--old", "1234", "4321" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId);
+    }
+
+    @Test
+    public void testClear() throws Exception {
+        when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true);
+        when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false);
+        when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true);
+        assertEquals(0, mCommand.exec(new Binder(), in, out, err,
+                new String[] { "clear", "--old", "1234" },
+                mShellCallback, mResultReceiver));
+        verify(mLockPatternUtils).clearLock("1234", mUserId);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
new file mode 100644
index 0000000..4bdd1c5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTestable.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import android.content.Context;
+
+import java.io.File;
+
+public class LockSettingsStorageTestable extends LockSettingsStorage {
+
+    public File mStorageDir;
+
+    public LockSettingsStorageTestable(Context context, File storageDir) {
+        super(context);
+        mStorageDir = storageDir;
+    }
+
+    @Override
+    String getLockPatternFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPatternFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getLockPasswordFilename(int userId) {
+        return makeDirs(mStorageDir,
+                super.getLockPasswordFilename(userId)).getAbsolutePath();
+    }
+
+    @Override
+    String getChildProfileLockFile(int userId) {
+        return makeDirs(mStorageDir,
+                super.getChildProfileLockFile(userId)).getAbsolutePath();
+    }
+
+    @Override
+    protected File getSyntheticPasswordDirectoryForUser(int userId) {
+        return makeDirs(mStorageDir, super.getSyntheticPasswordDirectoryForUser(
+                userId).getAbsolutePath());
+    }
+
+    private File makeDirs(File baseDir, String filePath) {
+        File path = new File(filePath);
+        if (path.getParent() == null) {
+            return new File(baseDir, filePath);
+        } else {
+            File mappedDir = new File(baseDir, path.getParent());
+            mappedDir.mkdirs();
+            return new File(mappedDir, path.getName());
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
new file mode 100644
index 0000000..4665441
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.FileUtils;
+import android.os.UserManager;
+import android.test.AndroidTestCase;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.LockSettingsStorageTests
+ */
+public class LockSettingsStorageTests extends AndroidTestCase {
+    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
+    private final byte[] PASSWORD_1 = "password1".getBytes();
+    private final byte[] PATTERN_0 = "123654".getBytes();
+    private final byte[] PATTERN_1 = "147852369".getBytes();
+
+    LockSettingsStorage mStorage;
+    File mStorageDir;
+
+    private File mDb;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
+        mDb = getContext().getDatabasePath("locksettings.db");
+
+        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
+        assertTrue(FileUtils.deleteContents(mStorageDir));
+        assertTrue(!mDb.exists() || mDb.delete());
+
+        final UserManager mockUserManager = mock(UserManager.class);
+        // User 2 is a profile of user 1.
+        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
+        // User 3 is a profile of user 0.
+        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
+
+        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
+                mock(NotificationManager.class), mock(DevicePolicyManager.class));
+        mStorage = new LockSettingsStorageTestable(context,
+                new File(getContext().getFilesDir(), "locksettings"));
+        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
+                    @Override
+                    public void initialize(SQLiteDatabase db) {
+                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
+                    }
+                });
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mStorage.closeDatabase();
+    }
+
+    public void testKeyValue_InitializeWorked() {
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+        mStorage.clearCache();
+        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
+    }
+
+    public void testKeyValue_WriteThenRead() {
+        mStorage.writeKeyValue("key", "value", 0);
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+        mStorage.clearCache();
+        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
+    }
+
+    public void testKeyValue_DefaultValue() {
+        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
+        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
+    }
+
+    public void testKeyValue_Concurrency() {
+        final Object monitor = new Object();
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    synchronized (monitor) {
+                        try {
+                            monitor.wait();
+                        } catch (InterruptedException e) {
+                            return;
+                        }
+                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
+                        mStorage.readKeyValue("key", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        mStorage.writeKeyValue("key", "initalValue", 0);
+        synchronized (monitor) {
+            monitor.notifyAll();
+        }
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+        mStorage.clearCache();
+        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
+    }
+
+    public void testKeyValue_CacheStarvedWriter() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            final int threadId = i;
+            threads.add(new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        latch.await();
+                    } catch (InterruptedException e) {
+                        return;
+                    }
+                    if (threadId == 50) {
+                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
+                    } else {
+                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
+                    }
+                }
+            });
+            threads.get(i).start();
+        }
+        latch.countDown();
+        for (int i = 0; i < threads.size(); i++) {
+            try {
+                threads.get(i).join();
+            } catch (InterruptedException e) {
+            }
+        }
+        String cached = mStorage.readKeyValue("key", "default", 0);
+        mStorage.clearCache();
+        String storage = mStorage.readKeyValue("key", "default", 0);
+        assertEquals("Cached value didn't match stored value", storage, cached);
+    }
+
+    public void testRemoveUser() {
+        mStorage.writeKeyValue("key", "value", 0);
+        writePasswordBytes(PASSWORD_0, 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.writeKeyValue("key", "value", 1);
+        writePasswordBytes(PASSWORD_1, 1);
+        writePatternBytes(PATTERN_1, 1);
+
+        mStorage.removeUser(0);
+
+        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
+        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
+        assertPatternBytes(PATTERN_1, 1);
+    }
+
+    public void testCredential_Default() {
+        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
+    }
+
+    public void testPassword_Write() {
+        writePasswordBytes(PASSWORD_0, 0);
+
+        assertPasswordBytes(PASSWORD_0, 0);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 0);
+    }
+
+    public void testPassword_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 1);
+        writePasswordBytes(PASSWORD_1, 2);
+
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_0, 1);
+        assertPasswordBytes(PASSWORD_1, 2);
+    }
+
+    public void testLockType_WriteProfileWritesParent() {
+        writePasswordBytes(PASSWORD_0, 10);
+        writePatternBytes(PATTERN_0, 20);
+
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+        mStorage.clearCache();
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
+                mStorage.readCredentialHash(10).type);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                mStorage.readCredentialHash(20).type);
+    }
+
+    public void testPassword_WriteParentWritesProfile() {
+        writePasswordBytes(PASSWORD_0, 2);
+        writePasswordBytes(PASSWORD_1, 1);
+
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+        mStorage.clearCache();
+        assertPasswordBytes(PASSWORD_1, 1);
+        assertPasswordBytes(PASSWORD_0, 2);
+    }
+
+    public void testProfileLock_ReadWriteChildProfileLock() {
+        assertFalse(mStorage.hasChildProfileLock(20));
+        mStorage.writeChildProfileLock(20, PASSWORD_0);
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+        mStorage.clearCache();
+        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
+        assertTrue(mStorage.hasChildProfileLock(20));
+    }
+
+    public void testPattern_Write() {
+        writePatternBytes(PATTERN_0, 0);
+
+        assertPatternBytes(PATTERN_0, 0);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testPattern_WriteProfileWritesParent() {
+        writePatternBytes(PATTERN_0, 1);
+        writePatternBytes(PATTERN_1, 2);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPattern_WriteParentWritesProfile() {
+        writePatternBytes(PATTERN_1, 2);
+        writePatternBytes(PATTERN_0, 1);
+
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+        mStorage.clearCache();
+        assertPatternBytes(PATTERN_0, 1);
+        assertPatternBytes(PATTERN_1, 2);
+    }
+
+    public void testPrefetch() {
+        mStorage.writeKeyValue("key", "toBeFetched", 0);
+        writePatternBytes(PATTERN_0, 0);
+
+        mStorage.clearCache();
+        mStorage.prefetchUser(0);
+
+        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
+        assertPatternBytes(PATTERN_0, 0);
+    }
+
+    public void testFileLocation_Owner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
+        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
+        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
+        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
+    }
+
+    public void testFileLocation_SecondaryUser() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
+        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
+    }
+
+    public void testFileLocation_ProfileToSecondary() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
+        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
+    }
+
+    public void testFileLocation_ProfileToOwner() {
+        LockSettingsStorage storage = new LockSettingsStorage(getContext());
+
+        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
+        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
+    }
+
+    public void testSyntheticPasswordState() {
+        final byte[] data = {1,2,3,4};
+        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
+        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
+
+        mStorage.deleteSyntheticPasswordState(10, 1234L, "state", true);
+        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
+    }
+
+    private static void assertArrayEquals(byte[] expected, byte[] actual) {
+        if (!Arrays.equals(expected, actual)) {
+            fail("expected:<" + Arrays.toString(expected) +
+                    "> but was:<" + Arrays.toString(actual) + ">");
+        }
+    }
+
+    private void writePasswordBytes(byte[] password, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
+    }
+
+    private void writePatternBytes(byte[] pattern, int userId) {
+        mStorage.writeCredentialHash(CredentialHash.create(
+                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
+    }
+
+    private void assertPasswordBytes(byte[] password, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
+        assertArrayEquals(password, cred.hash);
+    }
+
+    private void assertPatternBytes(byte[] pattern, int userId) {
+        CredentialHash cred = mStorage.readCredentialHash(userId);
+        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
+        assertArrayEquals(pattern, cred.hash);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
new file mode 100644
index 0000000..eefd361
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockGateKeeperService.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.service.gatekeeper.GateKeeperResponse;
+import android.service.gatekeeper.IGateKeeperService;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+public class MockGateKeeperService implements IGateKeeperService {
+    static class VerifyHandle {
+        public byte[] password;
+        public long sid;
+
+        public VerifyHandle(byte[] password, long sid) {
+            this.password = password;
+            this.sid = sid;
+        }
+
+        public VerifyHandle(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            sid = buffer.getLong();
+            password = new byte[buffer.remaining()];
+            buffer.get(password);
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + password.length);
+            buffer.put((byte)0);
+            buffer.putLong(sid);
+            buffer.put(password);
+            return buffer.array();
+        }
+    }
+
+    static class AuthToken {
+        public long challenge;
+        public long sid;
+
+        public AuthToken(long challenge, long sid) {
+            this.challenge = challenge;
+            this.sid = sid;
+        }
+
+        public AuthToken(byte[] handle) {
+            ByteBuffer buffer = ByteBuffer.allocate(handle.length);
+            buffer.put(handle, 0, handle.length);
+            buffer.flip();
+            int version = buffer.get();
+            challenge = buffer.getLong();
+            sid = buffer.getLong();
+        }
+
+        public byte[] toBytes() {
+            ByteBuffer buffer = ByteBuffer.allocate(1 + Long.BYTES + Long.BYTES);
+            buffer.put((byte)0);
+            buffer.putLong(challenge);
+            buffer.putLong(sid);
+            return buffer.array();
+        }
+    }
+
+    private ArrayMap<Integer, Long> sidMap = new ArrayMap<>();
+    private ArrayMap<Integer, AuthToken> authTokenMap = new ArrayMap<>();
+
+    private ArrayMap<Integer, byte[]> handleMap = new ArrayMap<>();
+
+    @Override
+    public GateKeeperResponse enroll(int uid, byte[] currentPasswordHandle, byte[] currentPassword,
+            byte[] desiredPassword) throws android.os.RemoteException {
+
+        if (currentPasswordHandle != null) {
+            VerifyHandle handle = new VerifyHandle(currentPasswordHandle);
+            if (Arrays.equals(currentPassword, handle.password)) {
+                // Trusted enroll
+                VerifyHandle newHandle = new VerifyHandle(desiredPassword, handle.sid);
+                refreshSid(uid, handle.sid, false);
+                handleMap.put(uid, newHandle.toBytes());
+                return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+            } else {
+                return null;
+            }
+        } else {
+            // Untrusted enroll
+            long newSid = new Random().nextLong();
+            VerifyHandle newHandle = new VerifyHandle(desiredPassword, newSid);
+            refreshSid(uid, newSid, true);
+            handleMap.put(uid, newHandle.toBytes());
+            return GateKeeperResponse.createOkResponse(newHandle.toBytes(), false);
+        }
+    }
+
+    @Override
+    public GateKeeperResponse verify(int uid, byte[] enrolledPasswordHandle,
+            byte[] providedPassword) throws android.os.RemoteException {
+        return verifyChallenge(uid, 0, enrolledPasswordHandle, providedPassword);
+    }
+
+    @Override
+    public GateKeeperResponse verifyChallenge(int uid, long challenge,
+            byte[] enrolledPasswordHandle, byte[] providedPassword) throws RemoteException {
+
+        VerifyHandle handle = new VerifyHandle(enrolledPasswordHandle);
+        if (Arrays.equals(handle.password, providedPassword)) {
+            byte[] knownHandle = handleMap.get(uid);
+            if (knownHandle != null) {
+                if (!Arrays.equals(knownHandle, enrolledPasswordHandle)) {
+                    throw new AssertionFailedError("Got correct but obsolete handle");
+                }
+            }
+            refreshSid(uid, handle.sid, false);
+            AuthToken token = new AuthToken(challenge, handle.sid);
+            refreshAuthToken(uid, token);
+            return GateKeeperResponse.createOkResponse(token.toBytes(), false);
+        } else {
+            return GateKeeperResponse.createGenericResponse(GateKeeperResponse.RESPONSE_ERROR);
+        }
+    }
+
+    private void refreshAuthToken(int uid, AuthToken token) {
+        authTokenMap.put(uid, token);
+    }
+
+    public AuthToken getAuthToken(int uid) {
+        return authTokenMap.get(uid);
+    }
+
+    public AuthToken getAuthTokenForSid(long sid) {
+        for(AuthToken token : authTokenMap.values()) {
+            if (token.sid == sid) {
+                return token;
+            }
+        }
+        return null;
+    }
+
+    public void clearAuthToken(int uid) {
+        authTokenMap.remove(uid);
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearSecureUserId(int userId) throws RemoteException {
+        sidMap.remove(userId);
+    }
+
+    @Override
+    public long getSecureUserId(int userId) throws RemoteException {
+        if (sidMap.containsKey(userId)) {
+            return sidMap.get(userId);
+        } else {
+            return 0L;
+        }
+    }
+
+    private void refreshSid(int uid, long sid, boolean force) {
+        if (!sidMap.containsKey(uid) || force) {
+            sidMap.put(uid, sid);
+        } else{
+            if (sidMap.get(uid) != sid) {
+                throw new AssertionFailedError("Inconsistent SID");
+            }
+        }
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
new file mode 100644
index 0000000..c76a83ef
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.UserManager;
+
+public class MockLockSettingsContext extends ContextWrapper {
+
+    private UserManager mUserManager;
+    private NotificationManager mNotificationManager;
+    private DevicePolicyManager mDevicePolicyManager;
+
+    public MockLockSettingsContext(Context base, UserManager userManager,
+            NotificationManager notificationManager, DevicePolicyManager devicePolicyManager) {
+        super(base);
+        mUserManager = userManager;
+        mNotificationManager = notificationManager;
+        mDevicePolicyManager = devicePolicyManager;
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        if (USER_SERVICE.equals(name)) {
+            return mUserManager;
+        } else if (NOTIFICATION_SERVICE.equals(name)) {
+            return mNotificationManager;
+        } else if (DEVICE_POLICY_SERVICE.equals(name)) {
+            return mDevicePolicyManager;
+        } else {
+            throw new RuntimeException("System service not mocked: " + name);
+        }
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        // Skip permission checks for unit tests.
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
new file mode 100644
index 0000000..ac46bae
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockStorageManager.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import android.content.pm.IPackageMoveObserver;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.storage.DiskInfo;
+import android.os.storage.IObbActionListener;
+import android.os.storage.IStorageEventListener;
+import android.os.storage.IStorageManager;
+import android.os.storage.IStorageShutdownObserver;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+import android.util.ArrayMap;
+import android.util.Pair;
+
+import com.android.internal.os.AppFuseMount;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockStorageManager implements IStorageManager {
+
+    private ArrayMap<Integer, ArrayList<Pair<byte[], byte[]>>> mAuth = new ArrayMap<>();
+    private boolean mIgnoreBadUnlock;
+
+    @Override
+    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        getUserAuth(userId).add(new Pair<>(token, secret));
+    }
+
+    @Override
+    public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
+        ArrayList<Pair<byte[], byte[]>> auths = mAuth.get(userId);
+        Pair<byte[], byte[]> latest = auths.get(auths.size() - 1);
+        auths.clear();
+        auths.add(latest);
+    }
+
+    private ArrayList<Pair<byte[], byte[]>> getUserAuth(int userId) {
+        if (!mAuth.containsKey(userId)) {
+            ArrayList<Pair<byte[], byte[]>> auths = new ArrayList<Pair<byte[], byte[]>>();
+            auths.add(new Pair(null, null));
+            mAuth.put(userId,  auths);
+        }
+        return mAuth.get(userId);
+    }
+
+    public byte[] getUserUnlockToken(int userId) {
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (auths.size() != 1) {
+            throw new AssertionFailedError("More than one secret exists");
+        }
+        return auths.get(0).second;
+    }
+
+    public void unlockUser(int userId, byte[] secret, IProgressListener listener)
+            throws RemoteException {
+        listener.onStarted(userId, null);
+        listener.onFinished(userId, null);
+        ArrayList<Pair<byte[], byte[]>> auths = getUserAuth(userId);
+        if (secret != null) {
+            if (auths.size() > 1) {
+                throw new AssertionFailedError("More than one secret exists");
+            }
+            Pair<byte[], byte[]> auth = auths.get(0);
+            if ((!mIgnoreBadUnlock) && auth.second != null && !Arrays.equals(secret, auth.second)) {
+                throw new AssertionFailedError("Invalid secret to unlock user");
+            }
+        } else {
+            if (auths != null && auths.size() > 0) {
+                throw new AssertionFailedError("Cannot unlock encrypted user with empty token");
+            }
+        }
+    }
+
+    public void setIgnoreBadUnlock(boolean ignore) {
+        mIgnoreBadUnlock = ignore;
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void registerListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unregisterListener(IStorageEventListener listener) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageConnected() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUsbMassStorageEnabled() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public int formatVolume(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int[] getStorageUsers(String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getVolumeState(String mountPoint) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid,
+            boolean external) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int finalizeSecureContainer(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int destroySecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int unmountSecureContainer(String id, boolean force) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSecureContainerMounted(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int renameSecureContainer(String oldId, String newId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerPath(String id) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSecureContainerList() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void shutdown(IStorageShutdownObserver observer) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void finishMediaUpdate() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mountObb(String rawPath, String canonicalPath, String key, IObbActionListener token,
+            int nonce) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isObbMounted(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getMountedObbPath(String rawPath) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isExternalStorageEmulated() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int decryptStorage(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int encryptStorage(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int changeEncryptionPassword(int type, String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSecureContainerFilesystemPath(String cid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getEncryptionState() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int verifyEncryptionPassword(String password) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int fixPermissionsSecureContainer(String id, int gid, String filename)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int mkdirs(String callingPkg, String path) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPasswordType() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearPassword() throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public void setField(String field, String contents) throws RemoteException {
+        throw new UnsupportedOperationException();
+
+    }
+
+    @Override
+    public String getField(String field) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long lastMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void runMaintenance() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void waitForAsecScan() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DiskInfo[] getDisks() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeInfo[] getVolumes(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void mount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unmount(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void format(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPublic(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionPrivate(String diskId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void partitionMixed(String diskId, int ratio) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetVolume(String fsUuid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void forgetAllVolumes() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPrimaryStorageUuid() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long benchmark(String volId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setDebugFlags(int flags, int mask) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void lockUserKey(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isUserKeyUnlocked(int userId) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void destroyUserStorage(String volumeUuid, int userId, int flags)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isConvertibleToFBE() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void fstrim(int flags) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AppFuseMount mountProxyFileDescriptorBridge() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ParcelFileDescriptor openProxyFileDescriptor(int mountPointId, int fileId, int mode)
+            throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheQuotaBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getCacheSizeBytes(String volumeUuid, int uid) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getAllocatableBytes(String path, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void allocateBytes(String path, long bytes, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
new file mode 100644
index 0000000..ddef5dc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+public class MockSyntheticPasswordManager extends SyntheticPasswordManager {
+
+    private MockGateKeeperService mGateKeeper;
+    private IWeaver mWeaverService;
+
+    public MockSyntheticPasswordManager(LockSettingsStorage storage,
+            MockGateKeeperService gatekeeper) {
+        super(storage);
+        mGateKeeper = gatekeeper;
+    }
+
+    private ArrayMap<String, byte[]> mBlobs = new ArrayMap<>();
+
+    @Override
+    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
+        if (mBlobs.containsKey(blobKeyName) && !Arrays.equals(mBlobs.get(blobKeyName), blob)) {
+            throw new AssertionFailedError("blobKeyName content is overwritten: " + blobKeyName);
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(blob.length);
+        buffer.put(blob, 0, blob.length);
+        buffer.flip();
+        int len;
+        len = buffer.getInt();
+        byte[] data = new byte[len];
+        buffer.get(data);
+        len = buffer.getInt();
+        byte[] appId = new byte[len];
+        buffer.get(appId);
+        long sid = buffer.getLong();
+        if (!Arrays.equals(appId, applicationId)) {
+            throw new AssertionFailedError("Invalid application id");
+        }
+        if (sid != 0 && mGateKeeper.getAuthTokenForSid(sid) == null) {
+            throw new AssertionFailedError("No valid auth token");
+        }
+        return data;
+    }
+
+    @Override
+    protected byte[] createSPBlob(String blobKeyName, byte[] data, byte[] applicationId, long sid) {
+        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES + data.length + Integer.BYTES
+                + applicationId.length + Long.BYTES);
+        buffer.putInt(data.length);
+        buffer.put(data);
+        buffer.putInt(applicationId.length);
+        buffer.put(applicationId);
+        buffer.putLong(sid);
+        byte[] result = buffer.array();
+        mBlobs.put(blobKeyName, result);
+        return result;
+    }
+
+    @Override
+    protected void destroySPBlobKey(String keyAlias) {
+    }
+
+    @Override
+    protected long sidFromPasswordHandle(byte[] handle) {
+        return new MockGateKeeperService.VerifyHandle(handle).sid;
+    }
+
+    @Override
+    protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
+        try {
+            PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 10, outLen * 8);
+            SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+            return f.generateSecret(spec).getEncoded();
+        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    protected IWeaver getWeaverService() throws RemoteException {
+        return mWeaverService;
+    }
+
+    public void enableWeaver() {
+        mWeaverService = new MockWeaverService();
+        initWeaverService();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
new file mode 100644
index 0000000..34831cd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockWeaverService.java
@@ -0,0 +1,108 @@
+package com.android.server.locksettings;
+
+import android.hardware.weaver.V1_0.IWeaver;
+import android.hardware.weaver.V1_0.WeaverConfig;
+import android.hardware.weaver.V1_0.WeaverReadResponse;
+import android.hardware.weaver.V1_0.WeaverStatus;
+import android.hidl.base.V1_0.DebugInfo;
+import android.os.IHwBinder;
+import android.os.IHwBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.Pair;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MockWeaverService implements IWeaver {
+
+    private static final int MAX_SLOTS = 8;
+    private static final int KEY_LENGTH = 256 / 8;
+    private static final int VALUE_LENGTH = 256 / 8;
+
+    private Pair<ArrayList<Byte>, ArrayList<Byte>>[] slots = new Pair[MAX_SLOTS];
+    @Override
+    public void getConfig(getConfigCallback cb) throws RemoteException {
+        WeaverConfig config = new WeaverConfig();
+        config.keySize = KEY_LENGTH;
+        config.valueSize = VALUE_LENGTH;
+        config.slots = MAX_SLOTS;
+        cb.onValues(WeaverStatus.OK, config);
+    }
+
+    @Override
+    public int write(int slotId, ArrayList<Byte> key, ArrayList<Byte> value)
+            throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+        slots[slotId] = Pair.create((ArrayList<Byte>) key.clone(), (ArrayList<Byte>) value.clone());
+        return WeaverStatus.OK;
+    }
+
+    @Override
+    public void read(int slotId, ArrayList<Byte> key, readCallback cb) throws RemoteException {
+        if (slotId < 0 || slotId >= MAX_SLOTS) {
+            throw new RuntimeException("Invalid slot id");
+        }
+
+        WeaverReadResponse response = new WeaverReadResponse();
+        if (key.equals(slots[slotId].first)) {
+            response.value.addAll(slots[slotId].second);
+            cb.onValues(WeaverStatus.OK, response);
+        } else {
+            cb.onValues(WeaverStatus.FAILED, response);
+        }
+    }
+
+    @Override
+    public IHwBinder asBinder() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<String> interfaceChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String interfaceDescriptor() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setHALInstrumentation() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean linkToDeath(DeathRecipient recipient, long cookie) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void ping() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DebugInfo getDebugInfo() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void notifySyspropsChanged() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean unlinkToDeath(DeathRecipient recipient) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ArrayList<byte[]> getHashChain() throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
new file mode 100644
index 0000000..0d35385
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.locksettings;
+
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_ENABLED_KEY;
+import static com.android.internal.widget.LockPatternUtils.SYNTHETIC_PASSWORD_HANDLE_KEY;
+
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationResult;
+import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
+
+
+/**
+ * runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
+ */
+public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testPasswordBasedSyntheticPassword() throws RemoteException {
+        final int USER_ID = 10;
+        final String PASSWORD = "user-password";
+        final String BADPASSWORD = "bad-password";
+        MockSyntheticPasswordManager manager = new MockSyntheticPasswordManager(mStorage, mGateKeeperService);
+        AuthenticationToken authToken = manager.newSyntheticPasswordAndSid(mGateKeeperService, null,
+                null, USER_ID);
+        long handle = manager.createPasswordBasedSyntheticPassword(mGateKeeperService, PASSWORD,
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, authToken, USER_ID);
+
+        AuthenticationResult result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, PASSWORD, USER_ID);
+        assertEquals(result.authToken.deriveKeyStorePassword(), authToken.deriveKeyStorePassword());
+
+        result = manager.unwrapPasswordBasedSyntheticPassword(mGateKeeperService, handle, BADPASSWORD, USER_ID);
+        assertNull(result.authToken);
+    }
+
+    private void disableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+    }
+
+    private void enableSyntheticPassword(int userId) throws RemoteException {
+        mService.setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
+    }
+
+    private boolean hasSyntheticPassword(int userId) throws RemoteException {
+        return mService.getLong(SYNTHETIC_PASSWORD_HANDLE_KEY, 0, userId) != 0;
+    }
+
+    public void testPasswordMigration() throws RemoteException {
+        final String PASSWORD = "testPasswordMigration-password";
+
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        // Performs migration
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+
+        // SP-based verification
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    private void initializeCredentialUnderSP(String password, int userId) throws RemoteException {
+        enableSyntheticPassword(userId);
+        mService.setLockCredential(password, password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD : LockPatternUtils.CREDENTIAL_TYPE_NONE, null, userId);
+    }
+
+    public void testSyntheticPasswordChangeCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordChangeCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordChangeCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
+        mGateKeeperService.clearSecureUserId(PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordVerifyCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordVerifyCredential-password";
+        final String BADPASSWORD = "testSyntheticPasswordVerifyCredential-badpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
+                mService.verifyCredential(BADPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+    public void testSyntheticPasswordClearCredential() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, PASSWORD, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordClearCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // clear password
+        mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // set a new password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertNotSame(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+    }
+
+    public void testSyntheticPasswordChangeCredentialUntrusted() throws RemoteException {
+        final String PASSWORD = "testSyntheticPasswordClearCredential-password";
+        final String NEWPASSWORD = "testSyntheticPasswordClearCredential-newpassword";
+
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        // Untrusted change password
+        mService.setLockCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        assertNotSame(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertNotSame(sid ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+
+        // Verify the password
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+    }
+
+
+    public void testManagedProfileUnifiedChallengeMigration() throws RemoteException {
+        final String UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd";
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        disableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testManagedProfileSeparateChallengeMigration() throws RemoteException {
+        final String primaryPassword = "testManagedProfileSeparateChallengeMigration-primary";
+        final String profilePassword = "testManagedProfileSeparateChallengeMigration-profile";
+        mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, PRIMARY_USER_ID);
+        mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null, MANAGED_PROFILE_USER_ID);
+        final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
+        final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
+        final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+        final byte[] profileStorageKey = mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID);
+        assertTrue(primarySid != 0);
+        assertTrue(profileSid != 0);
+        assertTrue(profileSid != primarySid);
+
+        // do migration
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        enableSyntheticPassword(MANAGED_PROFILE_USER_ID);
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+
+        // verify
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, MANAGED_PROFILE_USER_ID).getResponseCode());
+        assertEquals(primarySid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
+        assertArrayNotSame(primaryStorageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+        assertArrayNotSame(profileStorageKey, mStorageManager.getUserUnlockToken(MANAGED_PROFILE_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testTokenBasedResetPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedClearPassword() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
+        mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testTokenBasedResetPasswordAfterCredentialChanges() throws RemoteException {
+        final String PASSWORD = "password";
+        final String PATTERN = "123654";
+        final String NEWPASSWORD = "password";
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
+        final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode();
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+
+        mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD, PRIMARY_USER_ID);
+
+        mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(), PRIMARY_USER_ID);
+
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID).getResponseCode());
+        assertArrayEquals(storageKey, mStorageManager.getUserUnlockToken(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        enableSyntheticPassword(PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedImmediatelyIfNoUserPasswordNoMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        initializeCredentialUnderSP(null, PRIMARY_USER_ID);
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
+        assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
+    }
+
+    public void testEscrowTokenActivatedLaterWithUserPasswordNeedsMigration() throws RemoteException {
+        final String TOKEN = "some-high-entropy-secure-token";
+        final String PASSWORD = "password";
+        // Set up pre-SP user password
+        disableSyntheticPassword(PRIMARY_USER_ID);
+        mService.setLockCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+                PRIMARY_USER_ID);
+        enableSyntheticPassword(PRIMARY_USER_ID);
+
+        long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
+        // Token not activated immediately since user password exists
+        assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+        // Activate token (password gets migrated to SP at the same time)
+        assertEquals(VerifyCredentialResponse.RESPONSE_OK,
+                mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
+                        PRIMARY_USER_ID).getResponseCode());
+        // Verify token is activated
+        assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
+    }
+
+    // b/34600579
+    //TODO: add non-migration work profile case, and unify/un-unify transition.
+    //TODO: test token after user resets password
+    //TODO: test token based reset after unified work challenge
+    //TODO: test clear password after unified work challenge
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
new file mode 100644
index 0000000..5e56704
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
@@ -0,0 +1,11 @@
+package com.android.server.locksettings;
+
+public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mSpManager.enableWeaver();
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4c7bf4d..f4944f9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -7399,4 +7399,50 @@
                     "s21", "s22");
         });
     }
+
+    public void testReturnedByServer() {
+        // Package 1 updated, with manifest shortcuts.
+        addManifestShortcutResource(
+                new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+                R.xml.shortcut_1);
+        updatePackageVersion(CALLING_PACKAGE_1, 1);
+        mService.mPackageMonitor.onReceive(getTestContext(),
+                genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertWith(mManager.getManifestShortcuts())
+                    .haveIds("ms1")
+                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+
+            assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
+
+            assertWith(mManager.getDynamicShortcuts())
+                    .haveIds("s1")
+                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+        });
+
+        // Pin them.
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+                    list("ms1", "s1"), getCallingUser());
+            assertWith(getShortcutAsLauncher(USER_0))
+                    .haveIds("ms1", "s1")
+                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+        });
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertWith(mManager.getPinnedShortcuts())
+                    .haveIds("ms1", "s1")
+                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+        });
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            // This shows a warning log, but should still work.
+            assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts()));
+
+            assertWith(mManager.getDynamicShortcuts())
+                    .haveIds("s1")
+                    .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+        });
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
index 3789086..375edf3 100644
--- a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
@@ -20,16 +20,31 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.eq;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.app.job.JobService;
-import android.app.job.JobParameters;
+import android.app.job.JobServiceEngine;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageStats;
+import android.os.BatteryManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
 
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.storage.DiskStatsLoggingService.LogRunnable;
 
 import libcore.io.IoUtils;
@@ -46,14 +61,17 @@
 
 import java.io.File;
 import java.io.PrintStream;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 
 @RunWith(JUnit4.class)
 public class DiskStatsLoggingServiceTest extends AndroidTestCase {
     @Rule public TemporaryFolder mTemporaryFolder;
     @Rule public TemporaryFolder mDownloads;
-    @Rule public TemporaryFolder mRootDirectory;
     @Mock private AppCollector mCollector;
+    @Mock private JobService mJobService;
+    @Mock private StorageStatsManager mSsm;
+    private ExternalStorageStats mStorageStats;
     private File mInputFile;
 
 
@@ -66,8 +84,10 @@
         mInputFile = mTemporaryFolder.newFile();
         mDownloads = new TemporaryFolder();
         mDownloads.create();
-        mRootDirectory = new TemporaryFolder();
-        mRootDirectory.create();
+        mStorageStats = new ExternalStorageStats();
+        when(mSsm.queryExternalStatsForUser(isNull(String.class), any(UserHandle.class)))
+                .thenReturn(mStorageStats);
+        when(mJobService.getSystemService(anyString())).thenReturn(mSsm);
     }
 
     @Test
@@ -75,9 +95,9 @@
         LogRunnable task = new LogRunnable();
         task.setAppCollector(mCollector);
         task.setDownloadsDirectory(mDownloads.getRoot());
-        task.setRootDirectory(mRootDirectory.getRoot());
         task.setLogOutputFile(mInputFile);
         task.setSystemSize(0L);
+        task.setContext(mJobService);
         task.run();
 
         JSONObject json = getJsonOutput();
@@ -99,10 +119,10 @@
     public void testPopulatedLogTask() throws Exception {
         // Write data to directories.
         writeDataToFile(mDownloads.newFile(), "lol");
-        writeDataToFile(mRootDirectory.newFile("test.jpg"), "1234");
-        writeDataToFile(mRootDirectory.newFile("test.mp4"), "12345");
-        writeDataToFile(mRootDirectory.newFile("test.mp3"), "123456");
-        writeDataToFile(mRootDirectory.newFile("test.whatever"), "1234567");
+        mStorageStats.audioBytes = 6L;
+        mStorageStats.imageBytes = 4L;
+        mStorageStats.videoBytes = 5L;
+        mStorageStats.totalBytes = 22L;
 
         // Write apps.
         ArrayList<PackageStats> apps = new ArrayList<>();
@@ -110,15 +130,16 @@
         testApp.dataSize = 5L;
         testApp.cacheSize = 55L;
         testApp.codeSize = 10L;
+        testApp.userHandle = UserHandle.USER_SYSTEM;
         apps.add(testApp);
-        when(mCollector.getPackageStats(anyInt())).thenReturn(apps);
+        when(mCollector.getPackageStats(anyLong())).thenReturn(apps);
 
         LogRunnable task = new LogRunnable();
         task.setAppCollector(mCollector);
         task.setDownloadsDirectory(mDownloads.getRoot());
-        task.setRootDirectory(mRootDirectory.getRoot());
         task.setLogOutputFile(mInputFile);
         task.setSystemSize(10L);
+        task.setContext(mJobService);
         task.run();
 
         JSONObject json = getJsonOutput();
@@ -143,14 +164,57 @@
         LogRunnable task = new LogRunnable();
         task.setAppCollector(mCollector);
         task.setDownloadsDirectory(mDownloads.getRoot());
-        task.setRootDirectory(mRootDirectory.getRoot());
         task.setLogOutputFile(mInputFile);
         task.setSystemSize(10L);
+        task.setContext(mJobService);
         task.run();
 
         // No exception should be thrown.
     }
 
+    @Test
+    public void testDontCrashOnRun() throws Exception {
+        DiskStatsLoggingService service = spy(new DiskStatsLoggingService());
+        BatteryManager batteryManager = mock(BatteryManager.class);
+        when(batteryManager.isCharging()).thenReturn(true);
+        doReturn(batteryManager).when(service).getSystemService(Context.BATTERY_SERVICE);
+        UserManager userManager = mock(UserManager.class);
+        when(userManager.getUsers()).thenReturn(new ArrayList<>());
+        doReturn(userManager).when(service).getSystemService(Context.USER_SERVICE);
+        doReturn(mSsm).when(service).getSystemService(Context.STORAGE_STATS_SERVICE);
+        doReturn(mock(StorageManager.class))
+                .when(service)
+                .getSystemService(Context.STORAGE_SERVICE);
+
+        MockContentResolver cr = new MockContentResolver();
+        cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        doReturn(cr).when(service).getContentResolver();
+
+        PackageManager pm = mock(PackageManager.class);
+        VolumeInfo volumeInfo =
+                new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL, VolumeInfo.TYPE_PRIVATE, null, null);
+        when(pm.getPrimaryStorageCurrentVolume()).thenReturn(volumeInfo);
+        doReturn(pm).when(service).getPackageManager();
+
+        doReturn(0).when(service).getUserId();
+
+        // UGGGGGHHHHHHH! jobFinished is a final method on JobService which crashes when called if
+        // the JobService isn't initialized for real. ServiceTestCase doesn't let us initialize a
+        // service which is built into the framework without crashing, though, so we can't make a
+        // real initialized service.
+        //
+        // And so, we use reflection to set the JobServiceEngine, which is used by the final method,
+        // to be something which won't crash when called.
+        final Field field = JobService.class.getDeclaredField("mEngine");
+        field.setAccessible(true);
+        field.set(service, mock(JobServiceEngine.class));
+
+        // Note: This won't clobber your on-device cache file because, technically,
+        // FrameworkServicesTests don't have write permission to actually overwrite the cache file.
+        // We log and fail on the write silently in this case.
+        service.onStartJob(null);
+    }
+
     private void writeDataToFile(File f, String data) throws Exception{
         PrintStream out = new PrintStream(f);
         out.print(data);
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 876008b..46f10c1 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -173,8 +173,8 @@
         token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
 
         token.setFillsParent(false);
-        // Can not specify orientation if app doesn't fill parent.
-        assertEquals(SCREEN_ORIENTATION_UNSET, token.getOrientation());
+        // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25.
+        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
 
         token.setFillsParent(true);
         token.hidden = true;
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index 47ced99..d9349ed 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -66,8 +66,7 @@
     /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
     public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
             int userId) {
-        final Task newTask = new Task(WindowTestUtils.sNextTaskId++, stack, userId, service, null,
-                EMPTY, 0, false,
+        final Task newTask = new Task(sNextTaskId++, stack, userId, service, null, EMPTY, 0, false,
                 false, new ActivityManager.TaskDescription(), null);
         stack.addTask(newTask, POSITION_TOP);
         return newTask;
@@ -92,7 +91,7 @@
     public static class TestAppWindowToken extends AppWindowToken {
 
         TestAppWindowToken(DisplayContent dc) {
-            super(dc.mService, null, false, dc, true /* fillsParent */,
+            super(dc.mService, new IApplicationToken.Stub() {}, false, dc, true /* fillsParent */,
                     null /* overrideConfig */, null /* bounds */);
         }
 
diff --git a/services/tests/shortcutmanagerutils/Android.mk b/services/tests/shortcutmanagerutils/Android.mk
index dc97599..c7657f6 100644
--- a/services/tests/shortcutmanagerutils/Android.mk
+++ b/services/tests/shortcutmanagerutils/Android.mk
@@ -20,7 +20,8 @@
     $(call all-java-files-under, src)
 
 LOCAL_JAVA_LIBRARIES := \
-    mockito-target
+    mockito-target \
+    legacy-android-test
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index e13665b..16b73d5 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.usage;
 
+import static com.android.internal.util.ArrayUtils.defeatNullable;
+
 import android.app.AppOpsManager;
 import android.app.usage.ExternalStorageStats;
 import android.app.usage.IStorageStatsManager;
@@ -29,6 +31,7 @@
 import android.content.pm.PackageStats;
 import android.content.pm.UserInfo;
 import android.net.TrafficStats;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -112,9 +115,12 @@
         mStorage.registerListener(new StorageEventListener() {
             @Override
             public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
-                if ((vol.type == VolumeInfo.TYPE_PRIVATE)
-                        && (newState == VolumeInfo.STATE_MOUNTED)) {
-                    invalidateMounts();
+                switch (vol.type) {
+                    case VolumeInfo.TYPE_PRIVATE:
+                    case VolumeInfo.TYPE_EMULATED:
+                        if (newState == VolumeInfo.STATE_MOUNTED) {
+                            invalidateMounts();
+                        }
                 }
             }
         });
@@ -178,9 +184,11 @@
         long cacheBytes = 0;
         final long token = Binder.clearCallingIdentity();
         try {
-            for (UserInfo user : mUser.getUsers()) {
-                final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
-                cacheBytes += stats.cacheBytes;
+            if (isQuotaSupported(volumeUuid, callingPackage)) {
+                for (UserInfo user : mUser.getUsers()) {
+                    final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
+                    cacheBytes += stats.cacheBytes;
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -232,7 +240,7 @@
             enforcePermission(Binder.getCallingUid(), callingPackage);
         }
 
-        if (mPackage.getPackagesForUid(appInfo.uid).length == 1) {
+        if (defeatNullable(mPackage.getPackagesForUid(appInfo.uid)).length == 1) {
             // Only one package inside UID means we can fast-path
             return queryStatsForUid(volumeUuid, appInfo.uid, callingPackage);
         } else {
@@ -276,7 +284,7 @@
             enforcePermission(Binder.getCallingUid(), callingPackage);
         }
 
-        final String[] packageNames = mPackage.getPackagesForUid(uid);
+        final String[] packageNames = defeatNullable(mPackage.getPackagesForUid(uid));
         final long[] ceDataInodes = new long[packageNames.length];
         String[] codePaths = new String[0];
 
@@ -460,6 +468,7 @@
                     if (bytesDelta > mMinimumThresholdBytes) {
                         mPreviousBytes = mStats.getAvailableBytes();
                         recalculateQuotas(getInitializedStrategy());
+                        notifySignificantDelta();
                     }
                     sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
                     break;
@@ -511,4 +520,13 @@
         return Settings.Global.getInt(
                 resolver, Settings.Global.ENABLE_CACHE_QUOTA_CALCULATION, 1) != 0;
     }
+
+    /**
+     * Hacky way of notifying that disk space has changed significantly; we do
+     * this to cause "available space" values to be requeried.
+     */
+    void notifySignificantDelta() {
+        mContext.getContentResolver().notifyChange(
+                Uri.parse("content://com.android.externalstorage.documents/"), null, false);
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 84a2e8b..857d07a 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -906,7 +906,7 @@
                         if (!mConnected) {
                             // restore defaults when USB is disconnected
                             Slog.i(TAG, "Disconnect, setting usb functions to null");
-                            setEnabledFunctions(null, false, false);
+                            setEnabledFunctions(null, true, false);
                         }
                         updateUsbFunctions();
                     } else {
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 93cfd11..5399bb9 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -71,6 +71,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 class UsbProfileGroupSettingsManager {
     private static final String TAG = UsbProfileGroupSettingsManager.class.getSimpleName();
@@ -139,7 +140,7 @@
             } else {
                 UserPackage other = (UserPackage)obj;
 
-                return user.equals(user) && packageName.equals(other.packageName);
+                return user.equals(other.user) && packageName.equals(other.packageName);
             }
         }
 
@@ -319,21 +320,32 @@
             return false;
         }
 
-        public boolean matches(DeviceFilter f) {
-            if (mVendorId != -1 && f.mVendorId != mVendorId) return false;
-            if (mProductId != -1 && f.mProductId != mProductId) return false;
-            if (f.mManufacturerName != null && mManufacturerName == null) return false;
-            if (f.mProductName != null && mProductName == null) return false;
-            if (f.mSerialNumber != null && mSerialNumber == null) return false;
-            if (mManufacturerName != null && f.mManufacturerName != null &&
-                !mManufacturerName.equals(f.mManufacturerName)) return false;
-            if (mProductName != null && f.mProductName != null &&
-                !mProductName.equals(f.mProductName)) return false;
-            if (mSerialNumber != null && f.mSerialNumber != null &&
-                !mSerialNumber.equals(f.mSerialNumber)) return false;
+        /**
+         * If the device described by {@code device} covered by this filter?
+         *
+         * @param device The device
+         *
+         * @return {@code true} iff this filter covers the {@code device}
+         */
+        public boolean contains(DeviceFilter device) {
+            // -1 and null means "match anything"
+
+            if (mVendorId != -1 && device.mVendorId != mVendorId) return false;
+            if (mProductId != -1 && device.mProductId != mProductId) return false;
+            if (mManufacturerName != null && !Objects.equals(mManufacturerName,
+                    device.mManufacturerName)) {
+                return false;
+            }
+            if (mProductName != null && !Objects.equals(mProductName, device.mProductName)) {
+                return false;
+            }
+            if (mSerialNumber != null
+                    && !Objects.equals(mSerialNumber, device.mSerialNumber)) {
+                return false;
+            }
 
             // check device class/subclass/protocol
-            return matches(f.mClass, f.mSubclass, f.mProtocol);
+            return matches(device.mClass, device.mSubclass, device.mProtocol);
         }
 
         @Override
@@ -493,10 +505,19 @@
             return true;
         }
 
-        public boolean matches(AccessoryFilter f) {
-            if (mManufacturer != null && !f.mManufacturer.equals(mManufacturer)) return false;
-            if (mModel != null && !f.mModel.equals(mModel)) return false;
-            if (mVersion != null && !f.mVersion.equals(mVersion)) return false;
+        /**
+         * Is the accessories described {@code accessory} covered by this filter?
+         *
+         * @param accessory A filter describing the accessory
+         *
+         * @return {@code true} iff this the filter covers the accessory
+         */
+        public boolean contains(AccessoryFilter accessory) {
+            if (mManufacturer != null && !Objects.equals(accessory.mManufacturer, mManufacturer)) {
+                return false;
+            }
+            if (mModel != null && !Objects.equals(accessory.mModel, mModel)) return false;
+            if (mVersion != null && !Objects.equals(accessory.mVersion, mVersion)) return false;
             return true;
         }
 
@@ -539,16 +560,21 @@
     private class MyPackageMonitor extends PackageMonitor {
         @Override
         public void onPackageAdded(String packageName, int uid) {
-            handlePackageUpdate(packageName);
-        }
+            if (!mUserManager.isSameProfileGroup(mParentUser.getIdentifier(),
+                    UserHandle.getUserId(uid))) {
+                return;
+            }
 
-        @Override
-        public void onPackageUpdateFinished(String packageName, int uid) {
-            handlePackageUpdate(packageName);
+            handlePackageAdded(new UserPackage(packageName, UserHandle.getUserHandleForUid(uid)));
         }
 
         @Override
         public void onPackageRemoved(String packageName, int uid) {
+            if (!mUserManager.isSameProfileGroup(mParentUser.getIdentifier(),
+                    UserHandle.getUserId(uid))) {
+                return;
+            }
+
             clearDefaults(packageName, UserHandle.getUserHandleForUid(uid));
         }
     }
@@ -595,7 +621,7 @@
             readSettingsLocked();
         }
 
-        mPackageMonitor.register(context, null, true);
+        mPackageMonitor.register(context, null, UserHandle.ALL, true);
         mMtpNotificationManager = new MtpNotificationManager(
                 parentUserContext,
                 new MtpNotificationManager.OnOpenInAppListener() {
@@ -989,9 +1015,12 @@
 
         ApplicationInfo appInfo;
         try {
-            appInfo = mPackageManager.getApplicationInfo(component.getPackageName(), 0);
+            // Fixed handlers are always for parent user
+            appInfo = mPackageManager.getApplicationInfoAsUser(component.getPackageName(), 0,
+                    mParentUser.getIdentifier());
         } catch (NameNotFoundException e) {
-            Slog.e(TAG, "Default USB handling package not found: " + component.getPackageName());
+            Slog.e(TAG, "Default USB handling package (" + component.getPackageName()
+                    + ") not found  for user " + mParentUser);
             return;
         }
 
@@ -1175,10 +1204,10 @@
         if (userPackage != null) {
             // look for default activity
             for (final ResolveInfo info : matches) {
-                if (info.activityInfo != null
-                        && userPackage.packageName.equals(info.activityInfo.packageName)
-                        && userPackage.user.getIdentifier()
-                                == UserHandle.getUserId(info.activityInfo.applicationInfo.uid)) {
+                if (info.activityInfo != null && userPackage.equals(
+                        new UserPackage(info.activityInfo.packageName,
+                                UserHandle.getUserHandleForUid(
+                                        info.activityInfo.applicationInfo.uid)))) {
                     return info.activityInfo;
                 }
             }
@@ -1202,35 +1231,53 @@
         return null;
     }
 
-    private boolean clearCompatibleMatchesLocked(String packageName, DeviceFilter filter) {
-        boolean changed = false;
-        for (DeviceFilter test : mDevicePreferenceMap.keySet()) {
-            if (filter.matches(test)) {
-                UserPackage currentMatch = mDevicePreferenceMap.get(test);
-                if (!currentMatch.packageName.equals(packageName)) {
-                    mDevicePreferenceMap.remove(test);
-                    changed = true;
+    private boolean clearCompatibleMatchesLocked(@NonNull UserPackage userPackage,
+            @NonNull DeviceFilter filter) {
+        ArrayList<DeviceFilter> keysToRemove = new ArrayList<>();
+
+        // The keys in mDevicePreferenceMap are filters that match devices very narrowly
+        for (DeviceFilter device : mDevicePreferenceMap.keySet()) {
+            if (filter.contains(device)) {
+                UserPackage currentMatch = mDevicePreferenceMap.get(device);
+                if (!currentMatch.equals(userPackage)) {
+                    keysToRemove.add(device);
                 }
             }
         }
-        return changed;
+
+        if (!keysToRemove.isEmpty()) {
+            for (DeviceFilter keyToRemove : keysToRemove) {
+                mDevicePreferenceMap.remove(keyToRemove);
+            }
+        }
+
+        return !keysToRemove.isEmpty();
     }
 
-    private boolean clearCompatibleMatchesLocked(String packageName, AccessoryFilter filter) {
-        boolean changed = false;
-        for (AccessoryFilter test : mAccessoryPreferenceMap.keySet()) {
-            if (filter.matches(test)) {
-                UserPackage currentMatch = mAccessoryPreferenceMap.get(test);
-                if (!currentMatch.packageName.equals(packageName)) {
-                    mAccessoryPreferenceMap.remove(test);
-                    changed = true;
+    private boolean clearCompatibleMatchesLocked(@NonNull UserPackage userPackage,
+            @NonNull AccessoryFilter filter) {
+        ArrayList<AccessoryFilter> keysToRemove = new ArrayList<>();
+
+        // The keys in mAccessoryPreferenceMap are filters that match accessories very narrowly
+        for (AccessoryFilter accessory : mAccessoryPreferenceMap.keySet()) {
+            if (filter.contains(accessory)) {
+                UserPackage currentMatch = mAccessoryPreferenceMap.get(accessory);
+                if (!currentMatch.equals(userPackage)) {
+                    keysToRemove.add(accessory);
                 }
             }
         }
-        return changed;
+
+        if (!keysToRemove.isEmpty()) {
+            for (AccessoryFilter keyToRemove : keysToRemove) {
+                mAccessoryPreferenceMap.remove(keyToRemove);
+            }
+        }
+
+        return !keysToRemove.isEmpty();
     }
 
-    private boolean handlePackageUpdateLocked(String packageName, ActivityInfo aInfo,
+    private boolean handlePackageAddedLocked(UserPackage userPackage, ActivityInfo aInfo,
             String metaDataName) {
         XmlResourceParser parser = null;
         boolean changed = false;
@@ -1244,13 +1291,13 @@
                 String tagName = parser.getName();
                 if ("usb-device".equals(tagName)) {
                     DeviceFilter filter = DeviceFilter.read(parser);
-                    if (clearCompatibleMatchesLocked(packageName, filter)) {
+                    if (clearCompatibleMatchesLocked(userPackage, filter)) {
                         changed = true;
                     }
                 }
                 else if ("usb-accessory".equals(tagName)) {
                     AccessoryFilter filter = AccessoryFilter.read(parser);
-                    if (clearCompatibleMatchesLocked(packageName, filter)) {
+                    if (clearCompatibleMatchesLocked(userPackage, filter)) {
                         changed = true;
                     }
                 }
@@ -1265,17 +1312,18 @@
     }
 
     // Check to see if the package supports any USB devices or accessories.
-    // If so, clear any non-matching preferences for matching devices/accessories.
-    private void handlePackageUpdate(String packageName) {
+    // If so, clear any preferences for matching devices/accessories.
+    private void handlePackageAdded(@NonNull UserPackage userPackage) {
         synchronized (mLock) {
             PackageInfo info;
             boolean changed = false;
 
             try {
-                info = mPackageManager.getPackageInfo(packageName,
-                        PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+                info = mPackageManager.getPackageInfoAsUser(userPackage.packageName,
+                        PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA,
+                        userPackage.user.getIdentifier());
             } catch (NameNotFoundException e) {
-                Slog.e(TAG, "handlePackageUpdate could not find package " + packageName, e);
+                Slog.e(TAG, "handlePackageUpdate could not find package " + userPackage, e);
                 return;
             }
 
@@ -1283,11 +1331,12 @@
             if (activities == null) return;
             for (int i = 0; i < activities.length; i++) {
                 // check for meta-data, both for devices and accessories
-                if (handlePackageUpdateLocked(packageName, activities[i],
+                if (handlePackageAddedLocked(userPackage, activities[i],
                         UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                     changed = true;
                 }
-                if (handlePackageUpdateLocked(packageName, activities[i],
+
+                if (handlePackageAddedLocked(userPackage, activities[i],
                         UsbManager.ACTION_USB_ACCESSORY_ATTACHED)) {
                     changed = true;
                 }
@@ -1318,16 +1367,18 @@
      * @param user The user the package belongs to
      */
     void setDevicePackage(@NonNull UsbDevice device, @Nullable String packageName,
-            @Nullable UserHandle user) {
+            @NonNull UserHandle user) {
         DeviceFilter filter = new DeviceFilter(device);
         boolean changed = false;
         synchronized (mLock) {
             if (packageName == null) {
                 changed = (mDevicePreferenceMap.remove(filter) != null);
             } else {
-                changed = !packageName.equals(mDevicePreferenceMap.get(filter));
+                UserPackage userPackage = new UserPackage(packageName, user);
+
+                changed = !userPackage.equals(mDevicePreferenceMap.get(filter));
                 if (changed) {
-                    mDevicePreferenceMap.put(filter, new UserPackage(packageName, user));
+                    mDevicePreferenceMap.put(filter, userPackage);
                 }
             }
             if (changed) {
@@ -1344,16 +1395,18 @@
      * @param user The user the package belongs to
      */
     void setAccessoryPackage(@NonNull UsbAccessory accessory, @Nullable String packageName,
-            @Nullable UserHandle user) {
+            @NonNull UserHandle user) {
         AccessoryFilter filter = new AccessoryFilter(accessory);
         boolean changed = false;
         synchronized (mLock) {
             if (packageName == null) {
                 changed = (mAccessoryPreferenceMap.remove(filter) != null);
             } else {
-                changed = !packageName.equals(mAccessoryPreferenceMap.get(filter));
+                UserPackage userPackage = new UserPackage(packageName, user);
+
+                changed = !userPackage.equals(mAccessoryPreferenceMap.get(filter));
                 if (changed) {
-                    mAccessoryPreferenceMap.put(filter, new UserPackage(packageName, user));
+                    mAccessoryPreferenceMap.put(filter, userPackage);
                 }
             }
             if (changed) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e0788ca..fe37995 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -898,13 +898,6 @@
             "broadcast_emergency_call_state_changes_bool";
 
     /**
-     * Cell broadcast additional channels enbled by the carrier
-     * @hide
-     */
-    public static final String KEY_CARRIER_ADDITIONAL_CBS_CHANNELS_STRINGS =
-            "carrier_additional_cbs_channels_strings";
-
-    /**
       * Indicates whether STK LAUNCH_BROWSER command is disabled.
       * If {@code true}, then the browser will not be launched
       * on UI for the LAUNCH_BROWSER STK command.
diff --git a/telephony/java/android/telephony/MbmsDownloadManager.java b/telephony/java/android/telephony/MbmsDownloadManager.java
index 862c919..d9f8fa6 100644
--- a/telephony/java/android/telephony/MbmsDownloadManager.java
+++ b/telephony/java/android/telephony/MbmsDownloadManager.java
@@ -23,7 +23,7 @@
 import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.DownloadStatus;
 import android.telephony.mbms.IMbmsDownloadManagerCallback;
-import android.telephony.mbms.MbmsInitializationException;
+import android.telephony.mbms.MbmsException;
 import android.telephony.mbms.vendor.IMbmsDownloadService;
 import android.util.Log;
 
@@ -172,7 +172,7 @@
      */
     public static MbmsDownloadManager createManager(Context context,
             IMbmsDownloadManagerCallback listener, String downloadAppName)
-            throws MbmsInitializationException{
+            throws MbmsException {
         MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName,
                 SubscriptionManager.getDefaultSubscriptionId());
         mdm.bindAndInitialize();
@@ -190,19 +190,19 @@
 
     public static MbmsDownloadManager createManager(Context context,
             IMbmsDownloadManagerCallback listener, String downloadAppName, int subId)
-            throws MbmsInitializationException {
+            throws MbmsException {
         MbmsDownloadManager mdm = new MbmsDownloadManager(context, listener, downloadAppName,
                 subId);
         mdm.bindAndInitialize();
         return mdm;
     }
 
-    private void bindAndInitialize() throws MbmsInitializationException {
+    private void bindAndInitialize() throws MbmsException {
         // TODO: bind
         try {
             mService.initialize(mDownloadAppName, mSubId, mCallback);
         } catch (RemoteException e) {
-            throw new MbmsInitializationException(0); // TODO: proper error code
+            throw new MbmsException(0); // TODO: proper error code
         }
     }
 
diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java
index 770a04a..fc406ee 100644
--- a/telephony/java/android/telephony/MbmsStreamingManager.java
+++ b/telephony/java/android/telephony/MbmsStreamingManager.java
@@ -16,25 +16,68 @@
 
 package android.telephony;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.DeadObjectException;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.telephony.mbms.IMbmsStreamingManagerCallback;
 import android.telephony.mbms.IStreamingServiceCallback;
-import android.telephony.mbms.MbmsInitializationException;
+import android.telephony.mbms.MbmsException;
 import android.telephony.mbms.StreamingService;
 import android.telephony.mbms.StreamingServiceInfo;
 import android.telephony.mbms.vendor.IMbmsStreamingService;
 import android.util.Log;
 
+import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 /** @hide */
 public class MbmsStreamingManager {
+    private interface ServiceListener {
+        void onServiceConnected();
+        void onServiceDisconnected();
+    }
+
     private static final String LOG_TAG = "MbmsStreamingManager";
+    public static final String MBMS_STREAMING_SERVICE_ACTION =
+            "android.telephony.action.EmbmsStreaming";
+
     private static final boolean DEBUG = true;
+    private static final int BIND_TIMEOUT_MS = 3000;
+
     private IMbmsStreamingService mService;
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (service != null) {
+                Log.i(LOG_TAG, String.format("Connected to service %s", name));
+                synchronized (MbmsStreamingManager.this) {
+                    mService = IMbmsStreamingService.Stub.asInterface(service);
+                    mServiceListeners.forEach(ServiceListener::onServiceConnected);
+                }
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.i(LOG_TAG, String.format("Disconnected from service %s", name));
+            synchronized (MbmsStreamingManager.this) {
+                mService = null;
+                mServiceListeners.forEach(ServiceListener::onServiceDisconnected);
+            }
+        }
+    };
+    private List<ServiceListener> mServiceListeners = new LinkedList<>();
+
     private IMbmsStreamingManagerCallback mCallbackToApp;
     private final String mAppName;
 
@@ -54,9 +97,8 @@
      * Create a new MbmsStreamingManager using the given subscription ID.
      *
      * Note that this call will bind a remote service and that may take a bit.  This
-     * may throw an IllegalArgumentException or RemoteException.
-     * TODO: document this and add exceptions that can be thrown for synchronous
-     * initialization/bind errors
+     * may throw an {@link MbmsException}, indicating errors that may happen during
+     * the initialization or binding process.
      *
      * @param context
      * @param listener
@@ -66,7 +108,7 @@
      */
     public static MbmsStreamingManager create(Context context,
             IMbmsStreamingManagerCallback listener, String streamingAppName, int subscriptionId)
-            throws MbmsInitializationException {
+            throws MbmsException {
         MbmsStreamingManager manager = new MbmsStreamingManager(context, listener,
                 streamingAppName, subscriptionId);
         manager.bindAndInitialize();
@@ -81,9 +123,8 @@
      */
     public static MbmsStreamingManager create(Context context,
             IMbmsStreamingManagerCallback listener, String streamingAppName)
-            throws MbmsInitializationException {
-        // TODO: get default sub id
-        int subId = INVALID_SUBSCRIPTION_ID;
+            throws MbmsException {
+        int subId = SubscriptionManager.getDefaultSubscriptionId();
         MbmsStreamingManager manager = new MbmsStreamingManager(context, listener,
                 streamingAppName, subId);
         manager.bindAndInitialize();
@@ -94,8 +135,17 @@
      * Terminates this instance, ending calls to the registered listener.  Also terminates
      * any streaming services spawned from this instance.
      */
-    public void dispose() {
-        // service.dispose(streamingAppName);
+    public synchronized void dispose() {
+        if (mService == null) {
+            // Ignore and return, assume already disposed.
+            return;
+        }
+        try {
+            mService.dispose(mAppName, mSubscriptionId);
+        } catch (RemoteException e) {
+            // Ignore for now
+        }
+        mService = null;
     }
 
     /**
@@ -155,23 +205,79 @@
         return 0;
     }
 
-    private void logd(String str) {
-        Log.d(LOG_TAG, str);
-    }
+    private void bindAndInitialize() throws MbmsException {
+        // Query for the proper service
+        PackageManager packageManager = mContext.getPackageManager();
+        Intent queryIntent = new Intent();
+        queryIntent.setAction(MBMS_STREAMING_SERVICE_ACTION);
+        List<ResolveInfo> streamingServices = packageManager.queryIntentServices(queryIntent,
+                PackageManager.MATCH_SYSTEM_ONLY);
 
-    private boolean isServiceConnected() {
-        return mService != null;
-    }
+        if (streamingServices == null || streamingServices.size() == 0) {
+            throw new MbmsException(
+                    MbmsException.ERROR_NO_SERVICE_INSTALLED);
+        }
+        if (streamingServices.size() > 1) {
+            throw new MbmsException(
+                    MbmsException.ERROR_MULTIPLE_SERVICES_INSTALLED);
+        }
 
-    private void bindAndInitialize() throws MbmsInitializationException {
-        // TODO: bind to the service
-        try {
-            int returnCode = mService.initialize(mCallbackToApp, mAppName, mSubscriptionId);
-            if (returnCode != 0) {
-                throw new MbmsInitializationException(returnCode);
+        // Kick off the binding, and synchronously wait until binding is complete
+        final CountDownLatch latch = new CountDownLatch(1);
+        ServiceListener bindListener = new ServiceListener() {
+            @Override
+            public void onServiceConnected() {
+                latch.countDown();
             }
-        } catch (RemoteException e) {
-            throw new MbmsInitializationException(/* some error */ 0);
+
+            @Override
+            public void onServiceDisconnected() {
+            }
+        };
+
+        synchronized (this) {
+            mServiceListeners.add(bindListener);
+        }
+
+        Intent bindIntent = new Intent();
+        bindIntent.setComponent(streamingServices.get(0).getComponentInfo().getComponentName());
+
+        mContext.bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+
+        waitOnLatchWithTimeout(latch, BIND_TIMEOUT_MS);
+
+        // Remove the listener and call the initialization method through the interface.
+        synchronized (this) {
+            mServiceListeners.remove(bindListener);
+
+            if (mService == null) {
+                throw new MbmsException(MbmsException.ERROR_BIND_TIMEOUT_OR_FAILURE);
+            }
+
+            try {
+                int returnCode = mService.initialize(mCallbackToApp, mAppName, mSubscriptionId);
+                if (returnCode != MbmsException.SUCCESS) {
+                    throw new MbmsException(returnCode);
+                }
+            } catch (RemoteException e) {
+                mService = null;
+                Log.e(LOG_TAG, "Service died before initialization");
+                throw new MbmsException(MbmsException.ERROR_INITIALIZATION_REMOTE_EXCEPTION);
+            }
+        }
+    }
+
+    private static void waitOnLatchWithTimeout(CountDownLatch l, long timeoutMs) {
+        long endTime = System.currentTimeMillis() + timeoutMs;
+        while (System.currentTimeMillis() < endTime) {
+            try {
+                l.await(timeoutMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // keep waiting
+            }
+            if (l.getCount() <= 0) {
+                return;
+            }
         }
     }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 984344c..0dd6c0b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5779,35 +5779,75 @@
     }
 
     /**
-     * Set SIM card power state. Request is equivalent to inserting or removing the card.
+     * Requested state of SIM
      *
-     * @param powerUp True if powering up the SIM, otherwise powering down
+     * CARD_POWER_DOWN
+     * Powers down the SIM. SIM must be up prior.
+     *
+     * CARD_POWER_UP
+     * Powers up the SIM normally. SIM must be down prior.
+     *
+     * CARD_POWER_UP_PASS_THROUGH
+     * Powers up the SIM in PASS_THROUGH mode. SIM must be down prior.
+     * When SIM is powered up in PASS_THOUGH mode, the modem does not send
+     * any command to it (for example SELECT of MF, or TERMINAL CAPABILITY),
+     * and the SIM card is controlled completely by Telephony sending APDUs
+     * directly. The SIM card state will be RIL_CARDSTATE_PRESENT and the
+     * number of card apps will be 0.
+     * No new error code is generated. Emergency calls are supported in the
+     * same way as if the SIM card is absent.
+     * The PASS_THROUGH mode is valid only for the specific card session where it
+     * is activated, and normal behavior occurs at the next SIM initialization,
+     * unless PASS_THROUGH mode is requested again. Hence, the last power-up mode
+     * is NOT persistent across boots. On reboot, SIM will power up normally.
+     */
+    /** @hide */
+    public static final int CARD_POWER_DOWN = 0;
+    /** @hide */
+    public static final int CARD_POWER_UP = 1;
+    /** @hide */
+    public static final int CARD_POWER_UP_PASS_THROUGH = 2;
+
+    /**
+     * Set SIM card power state.
+     *
+     * @param state  State of SIM (power down, power up, pass through)
+     * @see #CARD_POWER_DOWN
+     * @see #CARD_POWER_UP
+     * @see #CARD_POWER_UP_PASS_THROUGH
+     * Callers should monitor for {@link TelephonyIntents#ACTION_SIM_STATE_CHANGED}
+     * broadcasts to determine success or failure and timeout if needed.
      *
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      *
      * @hide
      **/
-    public void setSimPowerState(boolean powerUp) {
-        setSimPowerStateForSlot(getSlotIndex(), powerUp);
+    public void setSimPowerState(int state) {
+        setSimPowerStateForSlot(getSlotIndex(), state);
     }
 
     /**
-     * Set SIM card power state. Request is equivalent to inserting or removing the card.
+     * Set SIM card power state.
      *
      * @param slotIndex SIM slot id
-     * @param powerUp True if powering up the SIM, otherwise powering down
+     * @param state  State of SIM (power down, power up, pass through)
+     * @see #CARD_POWER_DOWN
+     * @see #CARD_POWER_UP
+     * @see #CARD_POWER_UP_PASS_THROUGH
+     * Callers should monitor for {@link TelephonyIntents#ACTION_SIM_STATE_CHANGED}
+     * broadcasts to determine success or failure and timeout if needed.
      *
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      *
      * @hide
      **/
-    public void setSimPowerStateForSlot(int slotIndex, boolean powerUp) {
+    public void setSimPowerStateForSlot(int slotIndex, int state) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.setSimPowerStateForSlot(slotIndex, powerUp);
+                telephony.setSimPowerStateForSlot(slotIndex, state);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#setSimPowerStateForSlot", e);
diff --git a/telephony/java/android/telephony/mbms/MbmsException.java b/telephony/java/android/telephony/mbms/MbmsException.java
new file mode 100644
index 0000000..cc4a02a
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telephony.mbms;
+
+import android.os.RemoteException;
+
+/** @hide */
+public class MbmsException extends RemoteException {
+    public static final int SUCCESS = 0;
+    public static final int ERROR_NO_SERVICE_INSTALLED = 1;
+    public static final int ERROR_MULTIPLE_SERVICES_INSTALLED = 2;
+    public static final int ERROR_BIND_TIMEOUT_OR_FAILURE = 3;
+    public static final int ERROR_INITIALIZATION_REMOTE_EXCEPTION = 4;
+    public static final int ERROR_ALREADY_INITIALIZED = 5;
+
+    private final int mErrorCode;
+
+    /** @hide
+     * TODO: future systemapi
+     * */
+    public MbmsException(int errorCode) {
+        super();
+        mErrorCode = errorCode;
+    }
+
+    public int getErrorCode() {
+        return mErrorCode;
+    }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsInitializationException.java b/telephony/java/android/telephony/mbms/MbmsInitializationException.java
deleted file mode 100644
index 1612bc9..0000000
--- a/telephony/java/android/telephony/mbms/MbmsInitializationException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telephony.mbms;
-
-/** @hide */
-public class MbmsInitializationException extends Exception {
-    private final int mErrorCode;
-
-    /** @hide */
-    public MbmsInitializationException(int errorCode) {
-        super();
-        mErrorCode = errorCode;
-    }
-
-    public int getErrorCode() {
-        return mErrorCode;
-    }
-}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index bbfc490..7c74729 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1317,12 +1317,12 @@
     List<ClientRequestStats> getClientRequestStats(String callingPackage, int subid);
 
     /**
-     * Set SIM card power state. Request is equivalent to inserting or removing the card.
+     * Set SIM card power state.
      * @param slotIndex SIM slot id
-     * @param powerUp True if powering up the SIM, otherwise powering down
+     * @param state  State of SIM (power down, power up, pass through)
      * @hide
      * */
-    void setSimPowerStateForSlot(int slotIndex, boolean powerUp);
+    void setSimPowerStateForSlot(int slotIndex, int state);
 
     /**
      * Returns a list of Forbidden PLMNs from the specified SIM App
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index bce5680..f28d126 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -34,18 +34,6 @@
     public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50
             = 0x0032;
 
-    /** Channel 911 required by Taiwan NCC. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_911
-            = 0x038F; // 911
-
-    /** Channel 919 required by Taiwan NCC and Israel. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919
-            = 0x0397; // 919
-
-    /** Channel 928 required by Israel. ID 0~999 is allocated by GSMA */
-    public static final int MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_928
-            = 0x03A0; // 928
-
     /** Start of PWS Message Identifier range (includes ETWS and CMAS). */
     public static final int MESSAGE_ID_PWS_FIRST_IDENTIFIER
             = 0x1100; // 4352
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
index b550cfa..00bf33a 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
@@ -689,8 +689,20 @@
         AudioFormat format =  event.getCaptureAudioFormat();
         result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString());
         byte[] triggerAudio = event.getTriggerAudio();
-        result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
-        result = result + "CaptureSession: " + event.getCaptureSession();
+        result = result + ", TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
+        byte[] data = event.getData();
+        result = result + ", Data: " + (data == null ? "null" : data.length);
+        if (data != null) {
+          try {
+            String decodedData = new String(data, "UTF-8");
+            if (decodedData.chars().allMatch(c -> (c >= 32 && c < 128) || c == 0)) {
+                result = result + ", Decoded Data: '" + decodedData + "'";
+            }
+          } catch (Exception e) {
+            Log.e(TAG, "Failed to decode data");
+          }
+        }
+        result = result + ", CaptureSession: " + event.getCaptureSession();
         result += " )";
         return result;
     }
diff --git a/tests/SurfaceComposition/Android.mk b/tests/SurfaceComposition/Android.mk
index 95f69f1..d97c3f4 100644
--- a/tests/SurfaceComposition/Android.mk
+++ b/tests/SurfaceComposition/Android.mk
@@ -27,6 +27,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+
 LOCAL_PACKAGE_NAME := SurfaceComposition
 
 LOCAL_SDK_VERSION := current
diff --git a/tests/WindowAnimationJank/Android.mk b/tests/WindowAnimationJank/Android.mk
index 888ae64..f356afb 100644
--- a/tests/WindowAnimationJank/Android.mk
+++ b/tests/WindowAnimationJank/Android.mk
@@ -24,7 +24,11 @@
 
 LOCAL_PACKAGE_NAME := WindowAnimationJank
 
-LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator ub-janktesthelper
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ub-uiautomator \
+    ub-janktesthelper \
+    legacy-android-test \
+    junit
 
 LOCAL_SDK_VERSION := current
 
diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
index 978e5f5..a423c2a 100644
--- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -28,6 +28,7 @@
 import android.content.res.Resources;
 import android.net.NetworkStats;
 import android.net.TrafficStats;
+import android.support.test.filters.SmallTest;
 import android.test.AndroidTestCase;
 
 import com.android.frameworks.tests.net.R;
@@ -44,6 +45,7 @@
 /**
  * Tests for {@link NetworkStatsFactory}.
  */
+@SmallTest
 public class NetworkStatsFactoryTest extends AndroidTestCase {
     private File mTestProc;
     private NetworkStatsFactory mFactory;
@@ -72,9 +74,8 @@
     }
 
     public void testNetworkStatsDetail() throws Exception {
-        stageFile(R.raw.xt_qtaguid_typical, new File(mTestProc, "net/xt_qtaguid/stats"));
+        final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
 
-        final NetworkStats stats = mFactory.readNetworkStatsDetail();
         assertEquals(70, stats.size());
         assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 18621L, 2898L);
         assertStatsEntry(stats, "wlan0", 10011, SET_DEFAULT, 0x0, 35777L, 5718L);
@@ -98,9 +99,7 @@
     }
 
     public void testNetworkStatsWithSet() throws Exception {
-        stageFile(R.raw.xt_qtaguid_typical, new File(mTestProc, "net/xt_qtaguid/stats"));
-
-        final NetworkStats stats = mFactory.readNetworkStatsDetail();
+        final NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_typical);
         assertEquals(70, stats.size());
         assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L,
                 676L);
@@ -108,8 +107,7 @@
     }
 
     public void testNetworkStatsSingle() throws Exception {
-        stageFile(R.raw.xt_qtaguid_iface_typical,
-                new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
+        stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
 
         final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
         assertEquals(6, stats.size());
@@ -119,8 +117,7 @@
     }
 
     public void testNetworkStatsXt() throws Exception {
-        stageFile(R.raw.xt_qtaguid_iface_fmt_typical,
-                new File(mTestProc, "net/xt_qtaguid/iface_stat_fmt"));
+        stageFile(R.raw.xt_qtaguid_iface_fmt_typical, file("net/xt_qtaguid/iface_stat_fmt"));
 
         final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
         assertEquals(3, stats.size());
@@ -130,6 +127,67 @@
         assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
     }
 
+    public void testDoubleClatAccounting() throws Exception {
+        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+
+        // xt_qtaguid_with_clat_simple is a synthetic file that simulates
+        //  - 213 received 464xlat packets of size 200 bytes
+        //  - 41 sent 464xlat packets of size 100 bytes
+        //  - no other traffic on base interface for root uid.
+        NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple);
+        assertEquals(4, stats.size());
+
+        assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L);
+        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L);
+
+        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
+        assertEquals(42, stats.size());
+
+        assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L);
+        assertStatsEntry(stats, "v4-wlan0", 1000, SET_DEFAULT, 0x0, 30812L, 2310L);
+        assertStatsEntry(stats, "v4-wlan0", 10102, SET_DEFAULT, 0x0, 10022L, 3330L);
+        assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 9532772L, 254112L);
+        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 15229L, 5766L);
+        assertStatsEntry(stats, "wlan0", 1000, SET_DEFAULT, 0x0, 6126L, 2013L);
+        assertStatsEntry(stats, "wlan0", 10013, SET_DEFAULT, 0x0, 0L, 144L);
+        assertStatsEntry(stats, "wlan0", 10018, SET_DEFAULT, 0x0, 5980263L, 167667L);
+        assertStatsEntry(stats, "wlan0", 10060, SET_DEFAULT, 0x0, 134356L, 8705L);
+        assertStatsEntry(stats, "wlan0", 10079, SET_DEFAULT, 0x0, 10926L, 1507L);
+        assertStatsEntry(stats, "wlan0", 10102, SET_DEFAULT, 0x0, 25038L, 8245L);
+        assertStatsEntry(stats, "wlan0", 10103, SET_DEFAULT, 0x0, 0L, 192L);
+        assertStatsEntry(stats, "dummy0", 0, SET_DEFAULT, 0x0, 0L, 168L);
+        assertStatsEntry(stats, "lo", 0, SET_DEFAULT, 0x0, 1288L, 1288L);
+
+        NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
+    }
+
+    public void testDoubleClatAccounting100MBDownload() throws Exception {
+        // Downloading 100mb from an ipv4 only destination in a foreground activity
+
+        long appRxBytesBefore = 328684029L;
+        long appRxBytesAfter = 439237478L;
+        assertEquals("App traffic should be ~100MB", 110553449, appRxBytesAfter - appRxBytesBefore);
+
+        long rootRxBytesBefore = 1394011L;
+        long rootRxBytesAfter = 1398634L;
+        assertEquals("UID 0 traffic should be ~0", 4623, rootRxBytesAfter - rootRxBytesBefore);
+
+        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+        NetworkStats stats;
+
+        // Stats snapshot before the download
+        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_before);
+        assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesBefore, 5199872L);
+        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesBefore, 647888L);
+
+        // Stats snapshot after the download
+        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_after);
+        assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesAfter, 7867488L);
+        assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesAfter, 647587L);
+
+        NetworkStatsFactory.noteStackedIface("v4-wlan0", null);
+    }
+
     /**
      * Copy a {@link Resources#openRawResource(int)} into {@link File} for
      * testing purposes.
@@ -159,9 +217,22 @@
         }
     }
 
+    private File file(String path) throws Exception {
+        return new File(mTestProc, path);
+    }
+
+    private NetworkStats parseDetailedStats(int resourceId) throws Exception {
+        stageFile(resourceId, file("net/xt_qtaguid/stats"));
+        return mFactory.readNetworkStatsDetail();
+    }
+
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long txBytes) {
         final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
+        if (i < 0) {
+            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)",
+                    iface, uid, set, tag));
+        }
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -170,6 +241,10 @@
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
         final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
+        if (i < 0) {
+            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)",
+                    iface, uid, set, tag));
+        }
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 7a1c239..3172c6e 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -18,12 +18,13 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -47,6 +48,7 @@
 import android.os.Handler;
 import android.os.INetworkManagementService;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
 import android.os.test.TestLooper;
 import android.os.UserHandle;
 import android.support.test.filters.SmallTest;
@@ -352,6 +354,56 @@
                 mTethering.getLastTetherError(mTestIfname));
     }
 
-    // TODO: Test that a request for hotspot mode doesn't interface with an
+    @Test
+    public void failureEnablingIpForwarding() throws Exception {
+        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
+        when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
+        doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);
+
+        // Emulate pressing the WiFi tethering button.
+        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+        mLooper.dispatchAll();
+        verify(mWifiManager, times(1)).startSoftAp(null);
+        verifyNoMoreInteractions(mWifiManager);
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+
+        // Emulate externally-visible WifiManager effects, causing the
+        // per-interface state machine to start up, and telling us that
+        // tethering mode is to be started.
+        mTethering.interfaceStatusChanged(mTestIfname, true);
+        sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
+        mLooper.dispatchAll();
+
+        // Activity caused by test_wlan0 becoming available.
+        verify(mNMService, times(1)).listInterfaces();
+        // We verify get/set called twice here: once for setup and once during
+        // teardown because all events happen over the course of the single
+        // dispatchAll() above.
+        verify(mNMService, times(2)).getInterfaceConfig(mTestIfname);
+        verify(mNMService, times(2))
+                .setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
+        verify(mNMService, times(1)).tetherInterface(mTestIfname);
+        verify(mWifiManager).updateInterfaceIpState(
+                mTestIfname, WifiManager.IFACE_IP_MODE_TETHERED);
+        verify(mConnectivityManager, atLeastOnce()).isTetheringSupported();
+        verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
+        // This is called, but will throw.
+        verify(mNMService, times(1)).setIpForwardingEnabled(true);
+        // This never gets called because of the exception thrown above.
+        verify(mNMService, times(0)).startTethering(any(String[].class));
+        // When the master state machine transitions to an error state it tells
+        // downstream interfaces, which causes us to tell Wi-Fi about the error
+        // so it can take down AP mode.
+        verify(mNMService, times(1)).untetherInterface(mTestIfname);
+        verify(mWifiManager).updateInterfaceIpState(
+                mTestIfname, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
+
+        verifyNoMoreInteractions(mWifiManager);
+        verifyNoMoreInteractions(mConnectivityManager);
+        verifyNoMoreInteractions(mNMService);
+    }
+
+    // TODO: Test that a request for hotspot mode doesn't interfere with an
     // already operating tethering mode interface.
 }
diff --git a/tests/net/res/raw/xt_qtaguid_with_clat b/tests/net/res/raw/xt_qtaguid_with_clat
new file mode 100644
index 0000000..77e5c7b
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_with_clat
@@ -0,0 +1,43 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 v4-wlan0 0x0 0 0 256 5 196 4 256 5 0 0 0 0 196 4 0 0 0 0
+3 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 v4-wlan0 0x0 1000 0 30312 25 1770 27 30236 24 76 1 0 0 1694 26 76 1 0 0
+5 v4-wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6 v4-wlan0 0x0 10060 0 9398432 6717 169412 4235 9398432 6717 0 0 0 0 169412 4235 0 0 0 0
+7 v4-wlan0 0x0 10060 1 1448660 1041 31192 753 1448660 1041 0 0 0 0 31192 753 0 0 0 0
+8 v4-wlan0 0x0 10102 0 9702 16 2870 23 9702 16 0 0 0 0 2870 23 0 0 0 0
+9 v4-wlan0 0x0 10102 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+10 wlan0 0x0 0 0 11058671 7892 312046 5113 11043898 7811 13117 61 1656 20 306544 5046 3230 38 2272 29
+11 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+12 wlan0 0x0 1000 0 6126 13 2013 16 5934 11 192 2 0 0 1821 14 192 2 0 0
+13 wlan0 0x0 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+14 wlan0 0x0 10013 0 0 0 144 2 0 0 0 0 0 0 144 2 0 0 0 0
+15 wlan0 0x0 10013 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+16 wlan0 0x0 10018 0 5980263 4715 167667 1922 5972583 4709 0 0 7680 6 167667 1922 0 0 0 0
+17 wlan0 0x0 10018 1 43995 37 2766 27 43995 37 0 0 0 0 2766 27 0 0 0 0
+18 wlan0 0x0 10060 0 134356 133 8705 74 134356 133 0 0 0 0 8705 74 0 0 0 0
+19 wlan0 0x0 10060 1 294709 326 26448 256 294709 326 0 0 0 0 26448 256 0 0 0 0
+20 wlan0 0x0 10079 0 10926 13 1507 13 10926 13 0 0 0 0 1507 13 0 0 0 0
+21 wlan0 0x0 10079 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+22 wlan0 0x0 10102 0 25038 42 8245 57 25038 42 0 0 0 0 8245 57 0 0 0 0
+23 wlan0 0x0 10102 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+24 wlan0 0x0 10103 0 0 0 192 2 0 0 0 0 0 0 0 0 192 2 0 0
+25 wlan0 0x0 10103 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+26 wlan0 0x1000040700000000 10018 0 831 6 655 5 831 6 0 0 0 0 655 5 0 0 0 0
+27 wlan0 0x1000040700000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+28 wlan0 0x1000040b00000000 10018 0 1714 8 1561 7 1714 8 0 0 0 0 1561 7 0 0 0 0
+29 wlan0 0x1000040b00000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+30 wlan0 0x1000120300000000 10018 0 8243 11 2234 12 8243 11 0 0 0 0 2234 12 0 0 0 0
+31 wlan0 0x1000120300000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+32 wlan0 0x1000180300000000 10018 0 56368 49 4790 39 56368 49 0 0 0 0 4790 39 0 0 0 0
+33 wlan0 0x1000180300000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+34 wlan0 0x1000300000000000 10018 0 9488 17 18813 25 1808 11 0 0 7680 6 18813 25 0 0 0 0
+35 wlan0 0x1000300000000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+36 wlan0 0x3000180400000000 10018 0 131262 103 7416 103 131262 103 0 0 0 0 7416 103 0 0 0 0
+37 wlan0 0x3000180400000000 10018 1 43995 37 2766 27 43995 37 0 0 0 0 2766 27 0 0 0 0
+38 wlan0 0xffffff0100000000 10018 0 5771986 4518 131190 1725 5771986 4518 0 0 0 0 131190 1725 0 0 0 0
+39 wlan0 0xffffff0100000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+40 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3
+41 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+42 lo 0x0 0 0 1288 16 1288 16 0 0 532 8 756 8 0 0 532 8 756 8
+43 lo 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after
new file mode 100644
index 0000000..c78f84f
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_after
@@ -0,0 +1,187 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 r_rmnet_data0 0x0 0 0 0 0 392 6 0 0 0 0 0 0 0 0 0 0 392 6
+3 r_rmnet_data0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 v4-wlan0 0x0 0 0 58952 2072 2888 65 264 6 0 0 58688 2066 132 3 0 0 2756 62
+5 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6 v4-wlan0 0x0 10034 0 6192 11 1445 11 6192 11 0 0 0 0 1445 11 0 0 0 0
+7 v4-wlan0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+8 v4-wlan0 0x0 10057 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+9 v4-wlan0 0x0 10057 1 728 7 392 7 0 0 728 7 0 0 0 0 392 7 0 0
+10 v4-wlan0 0x0 10106 0 2232 18 2232 18 0 0 2232 18 0 0 0 0 2232 18 0 0
+11 v4-wlan0 0x0 10106 1 432952718 314238 5442288 121260 432950238 314218 2480 20 0 0 5433900 121029 8388 231 0 0
+12 wlan0 0x0 0 0 440746376 329772 8524052 130894 439660007 315369 232001 1276 854368 13127 7871216 121284 108568 1325 544268 8285
+13 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+14 wlan0 0x0 1000 0 77113 272 56151 575 77113 272 0 0 0 0 19191 190 36960 385 0 0
+15 wlan0 0x0 1000 1 20227 80 8356 72 18539 74 1688 6 0 0 7562 66 794 6 0 0
+16 wlan0 0x0 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0
+17 wlan0 0x0 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+18 wlan0 0x0 10015 0 4390 7 14824 252 4390 7 0 0 0 0 14824 252 0 0 0 0
+19 wlan0 0x0 10015 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+20 wlan0 0x0 10018 0 4928 11 1741 14 4928 11 0 0 0 0 1741 14 0 0 0 0
+21 wlan0 0x0 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+22 wlan0 0x0 10020 0 21163552 34395 2351650 15326 21162947 34390 605 5 0 0 2351045 15321 605 5 0 0
+23 wlan0 0x0 10020 1 13835740 12938 1548795 6365 13833754 12920 1986 18 0 0 1546809 6347 1986 18 0 0
+24 wlan0 0x0 10023 0 13405 40 5042 44 13405 40 0 0 0 0 5042 44 0 0 0 0
+25 wlan0 0x0 10023 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+26 wlan0 0x0 10034 0 436394741 342648 6237981 80442 436394741 342648 0 0 0 0 6237981 80442 0 0 0 0
+27 wlan0 0x0 10034 1 64860872 51297 1335539 15546 64860872 51297 0 0 0 0 1335539 15546 0 0 0 0
+28 wlan0 0x0 10044 0 17614444 14774 521004 5694 17329882 14432 284562 342 0 0 419974 5408 101030 286 0 0
+29 wlan0 0x0 10044 1 17701 33 3100 28 17701 33 0 0 0 0 3100 28 0 0 0 0
+30 wlan0 0x0 10057 0 12312074 9339 436098 5450 12248060 9263 64014 76 0 0 414224 5388 21874 62 0 0
+31 wlan0 0x0 10057 1 1332953195 954797 31849632 457698 1331933207 953569 1019988 1228 0 0 31702284 456899 147348 799 0 0
+32 wlan0 0x0 10060 0 32972 200 433705 380 32972 200 0 0 0 0 433705 380 0 0 0 0
+33 wlan0 0x0 10060 1 32106 66 37789 87 32106 66 0 0 0 0 37789 87 0 0 0 0
+34 wlan0 0x0 10061 0 7675 23 2509 22 7675 23 0 0 0 0 2509 22 0 0 0 0
+35 wlan0 0x0 10061 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+36 wlan0 0x0 10074 0 38355 82 10447 97 38355 82 0 0 0 0 10447 97 0 0 0 0
+37 wlan0 0x0 10074 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+38 wlan0 0x0 10078 0 49013 79 7167 69 49013 79 0 0 0 0 7167 69 0 0 0 0
+39 wlan0 0x0 10078 1 5872 8 1236 10 5872 8 0 0 0 0 1236 10 0 0 0 0
+40 wlan0 0x0 10082 0 8301 13 1981 15 8301 13 0 0 0 0 1981 15 0 0 0 0
+41 wlan0 0x0 10082 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+42 wlan0 0x0 10086 0 7001 14 1579 15 7001 14 0 0 0 0 1579 15 0 0 0 0
+43 wlan0 0x0 10086 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+44 wlan0 0x0 10090 0 24327795 20224 920502 14661 24327795 20224 0 0 0 0 920502 14661 0 0 0 0
+45 wlan0 0x0 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+46 wlan0 0x0 10092 0 36849 78 12449 81 36849 78 0 0 0 0 12449 81 0 0 0 0
+47 wlan0 0x0 10092 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0
+48 wlan0 0x0 10095 0 131962 223 37069 241 131962 223 0 0 0 0 37069 241 0 0 0 0
+49 wlan0 0x0 10095 1 12949 21 3930 21 12949 21 0 0 0 0 3930 21 0 0 0 0
+50 wlan0 0x0 10106 0 30899554 22679 632476 12296 30895334 22645 4220 34 0 0 628256 12262 4220 34 0 0
+51 wlan0 0x0 10106 1 88923475 64963 1606962 35612 88917201 64886 3586 29 2688 48 1602032 35535 4930 77 0 0
+52 wlan0 0x40700000000 10020 0 705732 10589 404428 5504 705732 10589 0 0 0 0 404428 5504 0 0 0 0
+53 wlan0 0x40700000000 10020 1 2376 36 1296 18 2376 36 0 0 0 0 1296 18 0 0 0 0
+54 wlan0 0x40800000000 10020 0 34624 146 122525 160 34624 146 0 0 0 0 122525 160 0 0 0 0
+55 wlan0 0x40800000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+56 wlan0 0x40b00000000 10020 0 22411 85 7364 57 22411 85 0 0 0 0 7364 57 0 0 0 0
+57 wlan0 0x40b00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+58 wlan0 0x120300000000 10020 0 76641 241 32783 169 76641 241 0 0 0 0 32783 169 0 0 0 0
+59 wlan0 0x120300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+60 wlan0 0x130100000000 10020 0 73101 287 23236 203 73101 287 0 0 0 0 23236 203 0 0 0 0
+61 wlan0 0x130100000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0
+62 wlan0 0x180300000000 10020 0 330648 399 24736 232 330648 399 0 0 0 0 24736 232 0 0 0 0
+63 wlan0 0x180300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+64 wlan0 0x180400000000 10020 0 21865 59 5022 42 21865 59 0 0 0 0 5022 42 0 0 0 0
+65 wlan0 0x180400000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+66 wlan0 0x300000000000 10020 0 15984 65 26927 57 15984 65 0 0 0 0 26927 57 0 0 0 0
+67 wlan0 0x300000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+68 wlan0 0x1065fff00000000 10020 0 131871 599 93783 445 131871 599 0 0 0 0 93783 445 0 0 0 0
+69 wlan0 0x1065fff00000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0
+70 wlan0 0x1b24f4600000000 10034 0 15445 42 23329 45 15445 42 0 0 0 0 23329 45 0 0 0 0
+71 wlan0 0x1b24f4600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+72 wlan0 0x1000010000000000 10020 0 5542 9 1364 10 5542 9 0 0 0 0 1364 10 0 0 0 0
+73 wlan0 0x1000010000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+74 wlan0 0x1000040100000000 10020 0 47196 184 213319 257 47196 184 0 0 0 0 213319 257 0 0 0 0
+75 wlan0 0x1000040100000000 10020 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0
+76 wlan0 0x1000040700000000 10020 0 11599 50 10786 47 11599 50 0 0 0 0 10786 47 0 0 0 0
+77 wlan0 0x1000040700000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+78 wlan0 0x1000040800000000 10020 0 21902 145 174139 166 21902 145 0 0 0 0 174139 166 0 0 0 0
+79 wlan0 0x1000040800000000 10020 1 8568 88 105743 90 8568 88 0 0 0 0 105743 90 0 0 0 0
+80 wlan0 0x1000100300000000 10020 0 55213 118 194551 199 55213 118 0 0 0 0 194551 199 0 0 0 0
+81 wlan0 0x1000100300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+82 wlan0 0x1000120300000000 10020 0 50826 74 21153 70 50826 74 0 0 0 0 21153 70 0 0 0 0
+83 wlan0 0x1000120300000000 10020 1 72 1 175 2 72 1 0 0 0 0 175 2 0 0 0 0
+84 wlan0 0x1000180300000000 10020 0 744198 657 65437 592 744198 657 0 0 0 0 65437 592 0 0 0 0
+85 wlan0 0x1000180300000000 10020 1 144719 132 10989 108 144719 132 0 0 0 0 10989 108 0 0 0 0
+86 wlan0 0x1000180600000000 10020 0 4599 8 1928 10 4599 8 0 0 0 0 1928 10 0 0 0 0
+87 wlan0 0x1000180600000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+88 wlan0 0x1000250000000000 10020 0 57740 98 13076 88 57740 98 0 0 0 0 13076 88 0 0 0 0
+89 wlan0 0x1000250000000000 10020 1 328 3 414 4 207 2 121 1 0 0 293 3 121 1 0 0
+90 wlan0 0x1000300000000000 10020 0 7675 30 31331 32 7675 30 0 0 0 0 31331 32 0 0 0 0
+91 wlan0 0x1000300000000000 10020 1 30173 97 101335 100 30173 97 0 0 0 0 101335 100 0 0 0 0
+92 wlan0 0x1000310200000000 10020 0 1681 9 2194 9 1681 9 0 0 0 0 2194 9 0 0 0 0
+93 wlan0 0x1000310200000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+94 wlan0 0x1000360000000000 10020 0 5606 20 2831 20 5606 20 0 0 0 0 2831 20 0 0 0 0
+95 wlan0 0x1000360000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+96 wlan0 0x11065fff00000000 10020 0 18363 91 83367 104 18363 91 0 0 0 0 83367 104 0 0 0 0
+97 wlan0 0x11065fff00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+98 wlan0 0x3000009600000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+99 wlan0 0x3000009600000000 10020 1 6163 18 2424 18 6163 18 0 0 0 0 2424 18 0 0 0 0
+100 wlan0 0x3000009800000000 10020 0 23337 46 8723 39 23337 46 0 0 0 0 8723 39 0 0 0 0
+101 wlan0 0x3000009800000000 10020 1 33744 93 72437 89 33744 93 0 0 0 0 72437 89 0 0 0 0
+102 wlan0 0x3000020000000000 10020 0 4124 11 8969 19 4124 11 0 0 0 0 8969 19 0 0 0 0
+103 wlan0 0x3000020000000000 10020 1 5993 11 3815 14 5993 11 0 0 0 0 3815 14 0 0 0 0
+104 wlan0 0x3000040100000000 10020 0 113809 342 135666 308 113809 342 0 0 0 0 135666 308 0 0 0 0
+105 wlan0 0x3000040100000000 10020 1 142508 642 500579 637 142508 642 0 0 0 0 500579 637 0 0 0 0
+106 wlan0 0x3000040700000000 10020 0 365815 5119 213340 2733 365815 5119 0 0 0 0 213340 2733 0 0 0 0
+107 wlan0 0x3000040700000000 10020 1 30747 130 18408 100 30747 130 0 0 0 0 18408 100 0 0 0 0
+108 wlan0 0x3000040800000000 10020 0 34672 112 68623 92 34672 112 0 0 0 0 68623 92 0 0 0 0
+109 wlan0 0x3000040800000000 10020 1 78443 199 140944 192 78443 199 0 0 0 0 140944 192 0 0 0 0
+110 wlan0 0x3000040b00000000 10020 0 14949 33 4017 26 14949 33 0 0 0 0 4017 26 0 0 0 0
+111 wlan0 0x3000040b00000000 10020 1 996 15 576 8 996 15 0 0 0 0 576 8 0 0 0 0
+112 wlan0 0x3000090000000000 10020 0 11826 67 7309 52 11826 67 0 0 0 0 7309 52 0 0 0 0
+113 wlan0 0x3000090000000000 10020 1 24805 41 4785 41 24805 41 0 0 0 0 4785 41 0 0 0 0
+114 wlan0 0x3000100300000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+115 wlan0 0x3000100300000000 10020 1 3112 10 1628 10 3112 10 0 0 0 0 1628 10 0 0 0 0
+116 wlan0 0x3000120300000000 10020 0 38249 107 20374 85 38249 107 0 0 0 0 20374 85 0 0 0 0
+117 wlan0 0x3000120300000000 10020 1 122581 174 36792 143 122581 174 0 0 0 0 36792 143 0 0 0 0
+118 wlan0 0x3000130100000000 10020 0 2700 41 1524 21 2700 41 0 0 0 0 1524 21 0 0 0 0
+119 wlan0 0x3000130100000000 10020 1 22515 59 8366 52 22515 59 0 0 0 0 8366 52 0 0 0 0
+120 wlan0 0x3000180200000000 10020 0 6411 18 14511 20 6411 18 0 0 0 0 14511 20 0 0 0 0
+121 wlan0 0x3000180200000000 10020 1 336 5 319 4 336 5 0 0 0 0 319 4 0 0 0 0
+122 wlan0 0x3000180300000000 10020 0 129301 136 17622 97 129301 136 0 0 0 0 17622 97 0 0 0 0
+123 wlan0 0x3000180300000000 10020 1 464787 429 41703 336 464787 429 0 0 0 0 41703 336 0 0 0 0
+124 wlan0 0x3000180400000000 10020 0 11014 39 2787 25 11014 39 0 0 0 0 2787 25 0 0 0 0
+125 wlan0 0x3000180400000000 10020 1 144040 139 7540 80 144040 139 0 0 0 0 7540 80 0 0 0 0
+126 wlan0 0x3000210100000000 10020 0 10278 44 4579 33 10278 44 0 0 0 0 4579 33 0 0 0 0
+127 wlan0 0x3000210100000000 10020 1 31151 73 14159 47 31151 73 0 0 0 0 14159 47 0 0 0 0
+128 wlan0 0x3000250000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0
+129 wlan0 0x3000250000000000 10020 1 76614 143 17711 130 76080 137 534 6 0 0 17177 124 534 6 0 0
+130 wlan0 0x3000260100000000 10020 0 9426 26 3535 20 9426 26 0 0 0 0 3535 20 0 0 0 0
+131 wlan0 0x3000260100000000 10020 1 468 7 288 4 468 7 0 0 0 0 288 4 0 0 0 0
+132 wlan0 0x3000300000000000 10020 0 7241 29 12055 26 7241 29 0 0 0 0 12055 26 0 0 0 0
+133 wlan0 0x3000300000000000 10020 1 3273 23 11232 21 3273 23 0 0 0 0 11232 21 0 0 0 0
+134 wlan0 0x3000310000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0
+135 wlan0 0x3000310000000000 10020 1 53425 64 8721 62 53425 64 0 0 0 0 8721 62 0 0 0 0
+136 wlan0 0x3000310500000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+137 wlan0 0x3000310500000000 10020 1 9929 16 3879 18 9929 16 0 0 0 0 3879 18 0 0 0 0
+138 wlan0 0x3000320100000000 10020 0 6844 14 3745 13 6844 14 0 0 0 0 3745 13 0 0 0 0
+139 wlan0 0x3000320100000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+140 wlan0 0x3000360000000000 10020 0 8855 43 4749 31 8855 43 0 0 0 0 4749 31 0 0 0 0
+141 wlan0 0x3000360000000000 10020 1 5597 19 2456 19 5597 19 0 0 0 0 2456 19 0 0 0 0
+142 wlan0 0x3010000000000000 10090 0 605140 527 38435 429 605140 527 0 0 0 0 38435 429 0 0 0 0
+143 wlan0 0x3010000000000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+144 wlan0 0x31065fff00000000 10020 0 22011 67 29665 64 22011 67 0 0 0 0 29665 64 0 0 0 0
+145 wlan0 0x31065fff00000000 10020 1 10695 34 18347 35 10695 34 0 0 0 0 18347 35 0 0 0 0
+146 wlan0 0x32e544f900000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+147 wlan0 0x32e544f900000000 10034 1 40143 54 7299 61 40143 54 0 0 0 0 7299 61 0 0 0 0
+148 wlan0 0x58872a4400000000 10018 0 4928 11 1669 13 4928 11 0 0 0 0 1669 13 0 0 0 0
+149 wlan0 0x58872a4400000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+150 wlan0 0x5caeaa7b00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+151 wlan0 0x5caeaa7b00000000 10034 1 74971 73 7103 75 74971 73 0 0 0 0 7103 75 0 0 0 0
+152 wlan0 0x9e00923800000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+153 wlan0 0x9e00923800000000 10034 1 72385 98 13072 110 72385 98 0 0 0 0 13072 110 0 0 0 0
+154 wlan0 0xb972bdd400000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+155 wlan0 0xb972bdd400000000 10034 1 15282 24 3034 27 15282 24 0 0 0 0 3034 27 0 0 0 0
+156 wlan0 0xc7c9f7ba00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+157 wlan0 0xc7c9f7ba00000000 10034 1 194915 185 13316 138 194915 185 0 0 0 0 13316 138 0 0 0 0
+158 wlan0 0xc9395b2600000000 10034 0 6991 13 6215 14 6991 13 0 0 0 0 6215 14 0 0 0 0
+159 wlan0 0xc9395b2600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+160 wlan0 0xdaddf21100000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+161 wlan0 0xdaddf21100000000 10034 1 928676 849 81570 799 928676 849 0 0 0 0 81570 799 0 0 0 0
+162 wlan0 0xe8d195d100000000 10020 0 516 8 288 4 516 8 0 0 0 0 288 4 0 0 0 0
+163 wlan0 0xe8d195d100000000 10020 1 5905 15 2622 15 5905 15 0 0 0 0 2622 15 0 0 0 0
+164 wlan0 0xe8d195d100000000 10034 0 236640 524 312523 555 236640 524 0 0 0 0 312523 555 0 0 0 0
+165 wlan0 0xe8d195d100000000 10034 1 319028 539 188776 553 319028 539 0 0 0 0 188776 553 0 0 0 0
+166 wlan0 0xffffff0100000000 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0
+167 wlan0 0xffffff0100000000 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+168 wlan0 0xffffff0100000000 10020 0 17874405 14068 223987 3065 17874405 14068 0 0 0 0 223987 3065 0 0 0 0
+169 wlan0 0xffffff0100000000 10020 1 11011258 8672 177693 2407 11011258 8672 0 0 0 0 177693 2407 0 0 0 0
+170 wlan0 0xffffff0100000000 10034 0 436062595 341880 5843990 79630 436062595 341880 0 0 0 0 5843990 79630 0 0 0 0
+171 wlan0 0xffffff0100000000 10034 1 63201220 49447 1005882 13713 63201220 49447 0 0 0 0 1005882 13713 0 0 0 0
+172 wlan0 0xffffff0100000000 10044 0 17159287 13702 356212 4778 17159287 13702 0 0 0 0 356212 4778 0 0 0 0
+173 wlan0 0xffffff0100000000 10044 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+174 wlan0 0xffffff0100000000 10078 0 10439 17 1665 15 10439 17 0 0 0 0 1665 15 0 0 0 0
+175 wlan0 0xffffff0100000000 10078 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+176 wlan0 0xffffff0100000000 10090 0 23722655 19697 881995 14231 23722655 19697 0 0 0 0 881995 14231 0 0 0 0
+177 wlan0 0xffffff0100000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+178 wlan0 0xffffff0500000000 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+179 wlan0 0xffffff0500000000 1000 1 1592 5 314 1 0 0 1592 5 0 0 0 0 314 1 0 0
+180 wlan0 0xffffff0600000000 1000 0 0 0 36960 385 0 0 0 0 0 0 0 0 36960 385 0 0
+181 wlan0 0xffffff0600000000 1000 1 96 1 480 5 0 0 96 1 0 0 0 0 480 5 0 0
+182 wlan0 0xffffff0700000000 1000 0 38732 229 16567 163 38732 229 0 0 0 0 16567 163 0 0 0 0
+183 wlan0 0xffffff0700000000 1000 1 18539 74 7562 66 18539 74 0 0 0 0 7562 66 0 0 0 0
+184 wlan0 0xffffff0900000000 1000 0 38381 43 2624 27 38381 43 0 0 0 0 2624 27 0 0 0 0
+185 wlan0 0xffffff0900000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+186 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3
+187 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before
new file mode 100644
index 0000000..d035387
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_with_clat_100mb_download_before
@@ -0,0 +1,185 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 r_rmnet_data0 0x0 0 0 0 0 392 6 0 0 0 0 0 0 0 0 0 0 392 6
+3 r_rmnet_data0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 v4-wlan0 0x0 0 0 58848 2070 2836 64 160 4 0 0 58688 2066 80 2 0 0 2756 62
+5 v4-wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6 v4-wlan0 0x0 10034 0 6192 11 1445 11 6192 11 0 0 0 0 1445 11 0 0 0 0
+7 v4-wlan0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+8 v4-wlan0 0x0 10057 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+9 v4-wlan0 0x0 10057 1 728 7 392 7 0 0 728 7 0 0 0 0 392 7 0 0
+10 v4-wlan0 0x0 10106 0 1488 12 1488 12 0 0 1488 12 0 0 0 0 1488 12 0 0
+11 v4-wlan0 0x0 10106 1 323981189 235142 3509032 84542 323979453 235128 1736 14 0 0 3502676 84363 6356 179 0 0
+12 wlan0 0x0 0 0 330187296 250652 5855801 94173 329106990 236273 226202 1255 854104 13124 5208040 84634 103637 1256 544124 8283
+13 wlan0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+14 wlan0 0x0 1000 0 77113 272 56151 575 77113 272 0 0 0 0 19191 190 36960 385 0 0
+15 wlan0 0x0 1000 1 20227 80 8356 72 18539 74 1688 6 0 0 7562 66 794 6 0 0
+16 wlan0 0x0 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0
+17 wlan0 0x0 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+18 wlan0 0x0 10015 0 4390 7 14824 252 4390 7 0 0 0 0 14824 252 0 0 0 0
+19 wlan0 0x0 10015 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+20 wlan0 0x0 10018 0 4928 11 1741 14 4928 11 0 0 0 0 1741 14 0 0 0 0
+21 wlan0 0x0 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+22 wlan0 0x0 10020 0 21141412 34316 2329881 15262 21140807 34311 605 5 0 0 2329276 15257 605 5 0 0
+23 wlan0 0x0 10020 1 13835740 12938 1548555 6362 13833754 12920 1986 18 0 0 1546569 6344 1986 18 0 0
+24 wlan0 0x0 10023 0 13405 40 5042 44 13405 40 0 0 0 0 5042 44 0 0 0 0
+25 wlan0 0x0 10023 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+26 wlan0 0x0 10034 0 436394741 342648 6237981 80442 436394741 342648 0 0 0 0 6237981 80442 0 0 0 0
+27 wlan0 0x0 10034 1 64860872 51297 1335539 15546 64860872 51297 0 0 0 0 1335539 15546 0 0 0 0
+28 wlan0 0x0 10044 0 17614444 14774 521004 5694 17329882 14432 284562 342 0 0 419974 5408 101030 286 0 0
+29 wlan0 0x0 10044 1 17701 33 3100 28 17701 33 0 0 0 0 3100 28 0 0 0 0
+30 wlan0 0x0 10057 0 12311735 9335 435954 5448 12247721 9259 64014 76 0 0 414080 5386 21874 62 0 0
+31 wlan0 0x0 10057 1 1332953195 954797 31849632 457698 1331933207 953569 1019988 1228 0 0 31702284 456899 147348 799 0 0
+32 wlan0 0x0 10060 0 32972 200 433705 380 32972 200 0 0 0 0 433705 380 0 0 0 0
+33 wlan0 0x0 10060 1 32106 66 37789 87 32106 66 0 0 0 0 37789 87 0 0 0 0
+34 wlan0 0x0 10061 0 7675 23 2509 22 7675 23 0 0 0 0 2509 22 0 0 0 0
+35 wlan0 0x0 10061 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+36 wlan0 0x0 10074 0 38355 82 10447 97 38355 82 0 0 0 0 10447 97 0 0 0 0
+37 wlan0 0x0 10074 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+38 wlan0 0x0 10078 0 49013 79 7167 69 49013 79 0 0 0 0 7167 69 0 0 0 0
+39 wlan0 0x0 10078 1 5872 8 1236 10 5872 8 0 0 0 0 1236 10 0 0 0 0
+40 wlan0 0x0 10082 0 8301 13 1981 15 8301 13 0 0 0 0 1981 15 0 0 0 0
+41 wlan0 0x0 10082 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+42 wlan0 0x0 10086 0 7001 14 1579 15 7001 14 0 0 0 0 1579 15 0 0 0 0
+43 wlan0 0x0 10086 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+44 wlan0 0x0 10090 0 24327795 20224 920502 14661 24327795 20224 0 0 0 0 920502 14661 0 0 0 0
+45 wlan0 0x0 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+46 wlan0 0x0 10092 0 36849 78 12449 81 36849 78 0 0 0 0 12449 81 0 0 0 0
+47 wlan0 0x0 10092 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0
+48 wlan0 0x0 10095 0 131962 223 37069 241 131962 223 0 0 0 0 37069 241 0 0 0 0
+49 wlan0 0x0 10095 1 12949 21 3930 21 12949 21 0 0 0 0 3930 21 0 0 0 0
+50 wlan0 0x0 10106 0 30899554 22679 632476 12296 30895334 22645 4220 34 0 0 628256 12262 4220 34 0 0
+51 wlan0 0x0 10106 1 88922349 64952 1605126 35599 88916075 64875 3586 29 2688 48 1600196 35522 4930 77 0 0
+52 wlan0 0x40700000000 10020 0 705732 10589 404428 5504 705732 10589 0 0 0 0 404428 5504 0 0 0 0
+53 wlan0 0x40700000000 10020 1 2376 36 1296 18 2376 36 0 0 0 0 1296 18 0 0 0 0
+54 wlan0 0x40800000000 10020 0 34624 146 122525 160 34624 146 0 0 0 0 122525 160 0 0 0 0
+55 wlan0 0x40800000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+56 wlan0 0x40b00000000 10020 0 22411 85 7364 57 22411 85 0 0 0 0 7364 57 0 0 0 0
+57 wlan0 0x40b00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+58 wlan0 0x120300000000 10020 0 76641 241 32783 169 76641 241 0 0 0 0 32783 169 0 0 0 0
+59 wlan0 0x120300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+60 wlan0 0x130100000000 10020 0 73101 287 23236 203 73101 287 0 0 0 0 23236 203 0 0 0 0
+61 wlan0 0x130100000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0
+62 wlan0 0x180300000000 10020 0 330648 399 24736 232 330648 399 0 0 0 0 24736 232 0 0 0 0
+63 wlan0 0x180300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+64 wlan0 0x180400000000 10020 0 21865 59 5022 42 21865 59 0 0 0 0 5022 42 0 0 0 0
+65 wlan0 0x180400000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+66 wlan0 0x300000000000 10020 0 15984 65 26927 57 15984 65 0 0 0 0 26927 57 0 0 0 0
+67 wlan0 0x300000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+68 wlan0 0x1065fff00000000 10020 0 131871 599 93783 445 131871 599 0 0 0 0 93783 445 0 0 0 0
+69 wlan0 0x1065fff00000000 10020 1 264 4 144 2 264 4 0 0 0 0 144 2 0 0 0 0
+70 wlan0 0x1b24f4600000000 10034 0 15445 42 23329 45 15445 42 0 0 0 0 23329 45 0 0 0 0
+71 wlan0 0x1b24f4600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+72 wlan0 0x1000010000000000 10020 0 5542 9 1364 10 5542 9 0 0 0 0 1364 10 0 0 0 0
+73 wlan0 0x1000010000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+74 wlan0 0x1000040100000000 10020 0 47196 184 213319 257 47196 184 0 0 0 0 213319 257 0 0 0 0
+75 wlan0 0x1000040100000000 10020 1 60 1 103 1 60 1 0 0 0 0 103 1 0 0 0 0
+76 wlan0 0x1000040700000000 10020 0 11599 50 10786 47 11599 50 0 0 0 0 10786 47 0 0 0 0
+77 wlan0 0x1000040700000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+78 wlan0 0x1000040800000000 10020 0 21902 145 174139 166 21902 145 0 0 0 0 174139 166 0 0 0 0
+79 wlan0 0x1000040800000000 10020 1 8568 88 105743 90 8568 88 0 0 0 0 105743 90 0 0 0 0
+80 wlan0 0x1000100300000000 10020 0 55213 118 194551 199 55213 118 0 0 0 0 194551 199 0 0 0 0
+81 wlan0 0x1000100300000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+82 wlan0 0x1000120300000000 10020 0 50826 74 21153 70 50826 74 0 0 0 0 21153 70 0 0 0 0
+83 wlan0 0x1000120300000000 10020 1 72 1 175 2 72 1 0 0 0 0 175 2 0 0 0 0
+84 wlan0 0x1000180300000000 10020 0 744198 657 65437 592 744198 657 0 0 0 0 65437 592 0 0 0 0
+85 wlan0 0x1000180300000000 10020 1 144719 132 10989 108 144719 132 0 0 0 0 10989 108 0 0 0 0
+86 wlan0 0x1000180600000000 10020 0 4599 8 1928 10 4599 8 0 0 0 0 1928 10 0 0 0 0
+87 wlan0 0x1000180600000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+88 wlan0 0x1000250000000000 10020 0 57740 98 13076 88 57740 98 0 0 0 0 13076 88 0 0 0 0
+89 wlan0 0x1000250000000000 10020 1 328 3 414 4 207 2 121 1 0 0 293 3 121 1 0 0
+90 wlan0 0x1000300000000000 10020 0 7675 30 31331 32 7675 30 0 0 0 0 31331 32 0 0 0 0
+91 wlan0 0x1000300000000000 10020 1 30173 97 101335 100 30173 97 0 0 0 0 101335 100 0 0 0 0
+92 wlan0 0x1000310200000000 10020 0 1681 9 2194 9 1681 9 0 0 0 0 2194 9 0 0 0 0
+93 wlan0 0x1000310200000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+94 wlan0 0x1000360000000000 10020 0 5606 20 2831 20 5606 20 0 0 0 0 2831 20 0 0 0 0
+95 wlan0 0x1000360000000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+96 wlan0 0x11065fff00000000 10020 0 18363 91 83367 104 18363 91 0 0 0 0 83367 104 0 0 0 0
+97 wlan0 0x11065fff00000000 10020 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+98 wlan0 0x3000009600000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+99 wlan0 0x3000009600000000 10020 1 6163 18 2424 18 6163 18 0 0 0 0 2424 18 0 0 0 0
+100 wlan0 0x3000009800000000 10020 0 23337 46 8723 39 23337 46 0 0 0 0 8723 39 0 0 0 0
+101 wlan0 0x3000009800000000 10020 1 33744 93 72437 89 33744 93 0 0 0 0 72437 89 0 0 0 0
+102 wlan0 0x3000020000000000 10020 0 4124 11 8969 19 4124 11 0 0 0 0 8969 19 0 0 0 0
+103 wlan0 0x3000020000000000 10020 1 5993 11 3815 14 5993 11 0 0 0 0 3815 14 0 0 0 0
+104 wlan0 0x3000040100000000 10020 0 106718 322 121557 287 106718 322 0 0 0 0 121557 287 0 0 0 0
+105 wlan0 0x3000040100000000 10020 1 142508 642 500579 637 142508 642 0 0 0 0 500579 637 0 0 0 0
+106 wlan0 0x3000040700000000 10020 0 365419 5113 213124 2730 365419 5113 0 0 0 0 213124 2730 0 0 0 0
+107 wlan0 0x3000040700000000 10020 1 30747 130 18408 100 30747 130 0 0 0 0 18408 100 0 0 0 0
+108 wlan0 0x3000040800000000 10020 0 34672 112 68623 92 34672 112 0 0 0 0 68623 92 0 0 0 0
+109 wlan0 0x3000040800000000 10020 1 78443 199 140944 192 78443 199 0 0 0 0 140944 192 0 0 0 0
+110 wlan0 0x3000040b00000000 10020 0 14949 33 4017 26 14949 33 0 0 0 0 4017 26 0 0 0 0
+111 wlan0 0x3000040b00000000 10020 1 996 15 576 8 996 15 0 0 0 0 576 8 0 0 0 0
+112 wlan0 0x3000090000000000 10020 0 4017 28 3610 25 4017 28 0 0 0 0 3610 25 0 0 0 0
+113 wlan0 0x3000090000000000 10020 1 24805 41 4545 38 24805 41 0 0 0 0 4545 38 0 0 0 0
+114 wlan0 0x3000100300000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+115 wlan0 0x3000100300000000 10020 1 3112 10 1628 10 3112 10 0 0 0 0 1628 10 0 0 0 0
+116 wlan0 0x3000120300000000 10020 0 38249 107 20374 85 38249 107 0 0 0 0 20374 85 0 0 0 0
+117 wlan0 0x3000120300000000 10020 1 122581 174 36792 143 122581 174 0 0 0 0 36792 143 0 0 0 0
+118 wlan0 0x3000130100000000 10020 0 2700 41 1524 21 2700 41 0 0 0 0 1524 21 0 0 0 0
+119 wlan0 0x3000130100000000 10020 1 22515 59 8366 52 22515 59 0 0 0 0 8366 52 0 0 0 0
+120 wlan0 0x3000180200000000 10020 0 6411 18 14511 20 6411 18 0 0 0 0 14511 20 0 0 0 0
+121 wlan0 0x3000180200000000 10020 1 336 5 319 4 336 5 0 0 0 0 319 4 0 0 0 0
+122 wlan0 0x3000180300000000 10020 0 129301 136 17622 97 129301 136 0 0 0 0 17622 97 0 0 0 0
+123 wlan0 0x3000180300000000 10020 1 464787 429 41703 336 464787 429 0 0 0 0 41703 336 0 0 0 0
+124 wlan0 0x3000180400000000 10020 0 11014 39 2787 25 11014 39 0 0 0 0 2787 25 0 0 0 0
+125 wlan0 0x3000180400000000 10020 1 144040 139 7540 80 144040 139 0 0 0 0 7540 80 0 0 0 0
+126 wlan0 0x3000210100000000 10020 0 10278 44 4579 33 10278 44 0 0 0 0 4579 33 0 0 0 0
+127 wlan0 0x3000210100000000 10020 1 31151 73 14159 47 31151 73 0 0 0 0 14159 47 0 0 0 0
+128 wlan0 0x3000250000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0
+129 wlan0 0x3000250000000000 10020 1 76614 143 17711 130 76080 137 534 6 0 0 17177 124 534 6 0 0
+130 wlan0 0x3000260100000000 10020 0 9426 26 3535 20 9426 26 0 0 0 0 3535 20 0 0 0 0
+131 wlan0 0x3000260100000000 10020 1 468 7 288 4 468 7 0 0 0 0 288 4 0 0 0 0
+132 wlan0 0x3000300000000000 10020 0 7241 29 12055 26 7241 29 0 0 0 0 12055 26 0 0 0 0
+133 wlan0 0x3000300000000000 10020 1 3273 23 11232 21 3273 23 0 0 0 0 11232 21 0 0 0 0
+134 wlan0 0x3000310000000000 10020 0 132 2 72 1 132 2 0 0 0 0 72 1 0 0 0 0
+135 wlan0 0x3000310000000000 10020 1 53425 64 8721 62 53425 64 0 0 0 0 8721 62 0 0 0 0
+136 wlan0 0x3000310500000000 10020 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+137 wlan0 0x3000310500000000 10020 1 9929 16 3879 18 9929 16 0 0 0 0 3879 18 0 0 0 0
+138 wlan0 0x3000360000000000 10020 0 8855 43 4749 31 8855 43 0 0 0 0 4749 31 0 0 0 0
+139 wlan0 0x3000360000000000 10020 1 5597 19 2456 19 5597 19 0 0 0 0 2456 19 0 0 0 0
+140 wlan0 0x3010000000000000 10090 0 605140 527 38435 429 605140 527 0 0 0 0 38435 429 0 0 0 0
+141 wlan0 0x3010000000000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+142 wlan0 0x31065fff00000000 10020 0 22011 67 29665 64 22011 67 0 0 0 0 29665 64 0 0 0 0
+143 wlan0 0x31065fff00000000 10020 1 10695 34 18347 35 10695 34 0 0 0 0 18347 35 0 0 0 0
+144 wlan0 0x32e544f900000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+145 wlan0 0x32e544f900000000 10034 1 40143 54 7299 61 40143 54 0 0 0 0 7299 61 0 0 0 0
+146 wlan0 0x58872a4400000000 10018 0 4928 11 1669 13 4928 11 0 0 0 0 1669 13 0 0 0 0
+147 wlan0 0x58872a4400000000 10018 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+148 wlan0 0x5caeaa7b00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+149 wlan0 0x5caeaa7b00000000 10034 1 74971 73 7103 75 74971 73 0 0 0 0 7103 75 0 0 0 0
+150 wlan0 0x9e00923800000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+151 wlan0 0x9e00923800000000 10034 1 72385 98 13072 110 72385 98 0 0 0 0 13072 110 0 0 0 0
+152 wlan0 0xb972bdd400000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+153 wlan0 0xb972bdd400000000 10034 1 15282 24 3034 27 15282 24 0 0 0 0 3034 27 0 0 0 0
+154 wlan0 0xc7c9f7ba00000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+155 wlan0 0xc7c9f7ba00000000 10034 1 194915 185 13316 138 194915 185 0 0 0 0 13316 138 0 0 0 0
+156 wlan0 0xc9395b2600000000 10034 0 6991 13 6215 14 6991 13 0 0 0 0 6215 14 0 0 0 0
+157 wlan0 0xc9395b2600000000 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+158 wlan0 0xdaddf21100000000 10034 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+159 wlan0 0xdaddf21100000000 10034 1 928676 849 81570 799 928676 849 0 0 0 0 81570 799 0 0 0 0
+160 wlan0 0xe8d195d100000000 10020 0 516 8 288 4 516 8 0 0 0 0 288 4 0 0 0 0
+161 wlan0 0xe8d195d100000000 10020 1 5905 15 2622 15 5905 15 0 0 0 0 2622 15 0 0 0 0
+162 wlan0 0xe8d195d100000000 10034 0 236640 524 312523 555 236640 524 0 0 0 0 312523 555 0 0 0 0
+163 wlan0 0xe8d195d100000000 10034 1 319028 539 188776 553 319028 539 0 0 0 0 188776 553 0 0 0 0
+164 wlan0 0xffffff0100000000 10006 0 80755 92 9122 99 80755 92 0 0 0 0 9122 99 0 0 0 0
+165 wlan0 0xffffff0100000000 10006 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+166 wlan0 0xffffff0100000000 10020 0 17874405 14068 223987 3065 17874405 14068 0 0 0 0 223987 3065 0 0 0 0
+167 wlan0 0xffffff0100000000 10020 1 11011258 8672 177693 2407 11011258 8672 0 0 0 0 177693 2407 0 0 0 0
+168 wlan0 0xffffff0100000000 10034 0 436062595 341880 5843990 79630 436062595 341880 0 0 0 0 5843990 79630 0 0 0 0
+169 wlan0 0xffffff0100000000 10034 1 63201220 49447 1005882 13713 63201220 49447 0 0 0 0 1005882 13713 0 0 0 0
+170 wlan0 0xffffff0100000000 10044 0 17159287 13702 356212 4778 17159287 13702 0 0 0 0 356212 4778 0 0 0 0
+171 wlan0 0xffffff0100000000 10044 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+172 wlan0 0xffffff0100000000 10078 0 10439 17 1665 15 10439 17 0 0 0 0 1665 15 0 0 0 0
+173 wlan0 0xffffff0100000000 10078 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+174 wlan0 0xffffff0100000000 10090 0 23722655 19697 881995 14231 23722655 19697 0 0 0 0 881995 14231 0 0 0 0
+175 wlan0 0xffffff0100000000 10090 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+176 wlan0 0xffffff0500000000 1000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+177 wlan0 0xffffff0500000000 1000 1 1592 5 314 1 0 0 1592 5 0 0 0 0 314 1 0 0
+178 wlan0 0xffffff0600000000 1000 0 0 0 36960 385 0 0 0 0 0 0 0 0 36960 385 0 0
+179 wlan0 0xffffff0600000000 1000 1 96 1 480 5 0 0 96 1 0 0 0 0 480 5 0 0
+180 wlan0 0xffffff0700000000 1000 0 38732 229 16567 163 38732 229 0 0 0 0 16567 163 0 0 0 0
+181 wlan0 0xffffff0700000000 1000 1 18539 74 7562 66 18539 74 0 0 0 0 7562 66 0 0 0 0
+182 wlan0 0xffffff0900000000 1000 0 38381 43 2624 27 38381 43 0 0 0 0 2624 27 0 0 0 0
+183 wlan0 0xffffff0900000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+184 dummy0 0x0 0 0 0 0 168 3 0 0 0 0 0 0 0 0 0 0 168 3
+185 dummy0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_simple b/tests/net/res/raw/xt_qtaguid_with_clat_simple
new file mode 100644
index 0000000..7f0e56f
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_with_clat_simple
@@ -0,0 +1,5 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 v4-wlan0 0x0 10060 0 42600 213 4100 41 42600 213 4100 41 0 0 0 0 0 0 0 0
+3 v4-wlan0 0x0 10060 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+4 wlan0 0x0 0 0 46860 213 4920 41 46860 213 4920 41 0 0 0 0 0 0 0 0
+5 wlan0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
index 82b2903..25432e3 100644
--- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java
+++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java
@@ -28,8 +28,10 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
@@ -38,10 +40,13 @@
 import static org.junit.Assume.*;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 /**
  * A test for broadcast radio API.
@@ -51,7 +56,9 @@
 
     public final Context mContext = InstrumentationRegistry.getContext();
 
-    private final int kConfigCallbacktimeoutNs = 10000;
+    private final int kConfigCallbackTimeoutMs = 10000;
+    private final int kCancelTimeoutMs = 1000;
+    private final int kTuneCallbackTimeoutMs = 30000;
 
     private RadioManager mRadioManager;
     private RadioTuner mRadioTuner;
@@ -89,12 +96,18 @@
             mRadioTuner.close();
             mRadioTuner = null;
         }
+        verifyNoMoreInteractions(mCallback);
     }
 
     private void openTuner() {
         openTuner(true);
     }
 
+    private void resetCallback() {
+        verifyNoMoreInteractions(mCallback);
+        Mockito.reset(mCallback);
+    }
+
     private void openTuner(boolean withAudio) {
         assertNull(mRadioTuner);
 
@@ -116,15 +129,19 @@
         mRadioTuner = mRadioManager.openTuner(module.getId(),
                 mFmBandConfig, withAudio, mCallback, null);
         assertNotNull(mRadioTuner);
-        verify(mCallback, timeout(kConfigCallbacktimeoutNs).times(1)).onConfigurationChanged(any());
-        verify(mCallback, never()).onError(anyInt());
-        Mockito.reset(mCallback);
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
+        resetCallback();
+    }
+
+    private void checkAntenna() {
+        // TODO(b/36863239): enable check when isAntennaConnected is implemented
+        //boolean isConnected = mRadioTuner.isAntennaConnected();
+        //assertTrue(isConnected);
     }
 
     @Test
     public void testOpenTuner() {
         openTuner();
-        verify(mCallback, never()).onError(anyInt());
     }
 
     @Test
@@ -134,7 +151,6 @@
         mRadioTuner = null;
         Thread.sleep(100);  // TODO(b/36122635): force reopen
         openTuner();
-        verify(mCallback, never()).onError(anyInt());
     }
 
     @Test
@@ -144,14 +160,13 @@
         // set
         int ret = mRadioTuner.setConfiguration(mAmBandConfig);
         assertEquals(RadioManager.STATUS_OK, ret);
-        verify(mCallback, timeout(kConfigCallbacktimeoutNs).times(1)).onConfigurationChanged(any());
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
 
         // get
         RadioManager.BandConfig[] config = new RadioManager.BandConfig[1];
         ret = mRadioTuner.getConfiguration(config);
         assertEquals(RadioManager.STATUS_OK, ret);
 
-        verify(mCallback, never()).onError(anyInt());
         assertEquals(mAmBandConfig, config[0]);
     }
 
@@ -179,9 +194,7 @@
         // setting good config should recover
         ret = mRadioTuner.setConfiguration(mAmBandConfig);
         assertEquals(RadioManager.STATUS_OK, ret);
-        verify(mCallback, timeout(kConfigCallbacktimeoutNs).times(1)).onConfigurationChanged(any());
-
-        verify(mCallback, never()).onError(anyInt());
+        verify(mCallback, timeout(kConfigCallbackTimeoutMs)).onConfigurationChanged(any());
     }
 
     @Test
@@ -212,4 +225,83 @@
         boolean isMuted = mRadioTuner.getMute();
         assertTrue(isMuted);
     }
+
+    @Test
+    public void testStep() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, true);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        resetCallback();
+
+        ret = mRadioTuner.step(RadioTuner.DIRECTION_UP, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+    }
+
+    @Test
+    public void testTuneAndGetPI() {
+        openTuner();
+        checkAntenna();
+
+        int channel = mFmBandConfig.getLowerLimit() + mFmBandConfig.getSpacing();
+
+        // test tune
+        int ret = mRadioTuner.tune(channel, 0);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        ArgumentCaptor<RadioManager.ProgramInfo> infoc =
+                ArgumentCaptor.forClass(RadioManager.ProgramInfo.class);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs))
+                .onProgramInfoChanged(infoc.capture());
+        assertEquals(channel, infoc.getValue().getChannel());
+
+        // test getProgramInformation
+        RadioManager.ProgramInfo[] info = new RadioManager.ProgramInfo[1];
+        ret = mRadioTuner.getProgramInformation(info);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        assertNotNull(info[0]);
+        assertEquals(channel, info[0].getChannel());
+    }
+
+    @Test
+    public void testDummyCancel() {
+        openTuner();
+
+        int ret = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, ret);
+    }
+
+    @Test
+    public void testLateCancel() {
+        openTuner();
+        checkAntenna();
+
+        int ret = mRadioTuner.step(RadioTuner.DIRECTION_DOWN, false);
+        assertEquals(RadioManager.STATUS_OK, ret);
+        verify(mCallback, timeout(kTuneCallbackTimeoutMs)).onProgramInfoChanged(any());
+
+        int cancelRet = mRadioTuner.cancel();
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+    }
+
+    @Test
+    public void testScanAndCancel() {
+        openTuner();
+        checkAntenna();
+
+        /* There is a possible race condition between scan and cancel commands - the scan may finish
+         * before cancel command is issued. Thus we accept both outcomes in this test.
+         */
+        int scanRet = mRadioTuner.scan(RadioTuner.DIRECTION_DOWN, true);
+        int cancelRet = mRadioTuner.cancel();
+
+        assertEquals(RadioManager.STATUS_OK, scanRet);
+        assertEquals(RadioManager.STATUS_OK, cancelRet);
+
+        verify(mCallback, after(kCancelTimeoutMs).atMost(1)).onError(RadioTuner.ERROR_CANCELLED);
+        verify(mCallback, atMost(1)).onProgramInfoChanged(any());
+    }
 }
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 57c4574..aa94723 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -31,21 +31,22 @@
 
 namespace aapt {
 
-void DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
+bool DumpCompiledFile(const pb::CompiledFile& pb_file, const void* data, size_t len,
                       const Source& source, IAaptContext* context) {
   std::unique_ptr<ResourceFile> file =
       DeserializeCompiledFileFromPb(pb_file, source, context->GetDiagnostics());
   if (!file) {
     context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-    return;
+    return false;
   }
 
   std::cout << "Resource: " << file->name << "\n"
             << "Config:   " << file->config << "\n"
             << "Source:   " << file->source << "\n";
+  return true;
 }
 
-void TryDumpFile(IAaptContext* context, const std::string& file_path) {
+bool TryDumpFile(IAaptContext* context, const std::string& file_path) {
   std::unique_ptr<ResourceTable> table;
 
   std::string err;
@@ -57,18 +58,18 @@
       if (!data) {
         context->GetDiagnostics()->Error(DiagMessage(file_path)
                                          << "failed to open resources.arsc.flat");
-        return;
+        return false;
       }
 
       pb::ResourceTable pb_table;
       if (!pb_table.ParseFromArray(data->data(), data->size())) {
         context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat");
-        return;
+        return false;
       }
 
       table = DeserializeTableFromPb(pb_table, Source(file_path), context->GetDiagnostics());
       if (!table) {
-        return;
+        return false;
       }
     }
 
@@ -79,14 +80,14 @@
         if (!data) {
           context->GetDiagnostics()->Error(DiagMessage(file_path)
                                            << "failed to open resources.arsc");
-          return;
+          return false;
         }
 
         table = util::make_unique<ResourceTable>();
         BinaryResourceParser parser(context, table.get(), Source(file_path), data->data(),
                                     data->size());
         if (!parser.Parse()) {
-          return;
+          return false;
         }
       }
     }
@@ -96,7 +97,7 @@
     Maybe<android::FileMap> file = file::MmapPath(file_path, &err);
     if (!file) {
       context->GetDiagnostics()->Error(DiagMessage(file_path) << err);
-      return;
+      return false;
     }
 
     android::FileMap* file_map = &file.value();
@@ -113,24 +114,26 @@
 
       uint32_t num_files = 0;
       if (!input.ReadLittleEndian32(&num_files)) {
-        return;
+        return false;
       }
 
       for (uint32_t i = 0; i < num_files; i++) {
         pb::CompiledFile compiled_file;
         if (!input.ReadCompiledFile(&compiled_file)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read compiled file");
-          return;
+          return false;
         }
 
         uint64_t offset, len;
         if (!input.ReadDataMetaData(&offset, &len)) {
           context->GetDiagnostics()->Warn(DiagMessage() << "failed to read meta data");
-          return;
+          return false;
         }
 
         const void* data = static_cast<const uint8_t*>(file_map->getDataPtr()) + offset;
-        DumpCompiledFile(compiled_file, data, len, Source(file_path), context);
+        if (!DumpCompiledFile(compiled_file, data, len, Source(file_path), context)) {
+          return false;
+        }
       }
     }
   }
@@ -140,6 +143,8 @@
     options.show_sources = true;
     Debug::PrintTable(table.get(), options);
   }
+
+  return true;
 }
 
 class DumpContext : public IAaptContext {
@@ -203,8 +208,11 @@
   context.SetVerbose(verbose);
 
   for (const std::string& arg : flags.GetArgs()) {
-    TryDumpFile(&context, arg);
+    if (!TryDumpFile(&context, arg)) {
+      return 1;
+    }
   }
+
   return 0;
 }
 
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index ce84993..064d365 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -402,4 +402,22 @@
   EXPECT_EQ(nullptr, Verify(input));
 }
 
+TEST_F(ManifestFixerTest, IgnoreNamespacedElements) {
+  std::string input = R"EOF(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                package="android">
+        <special:tag whoo="true" xmlns:special="http://google.com" />
+      </manifest>)EOF";
+  EXPECT_NE(nullptr, Verify(input));
+}
+
+TEST_F(ManifestFixerTest, DoNotIgnoreNonNamespacedElements) {
+  std::string input = R"EOF(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                package="android">
+        <tag whoo="true" />
+      </manifest>)EOF";
+  EXPECT_EQ(nullptr, Verify(input));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp
index 7580b46..352a933 100644
--- a/tools/aapt2/xml/XmlActionExecutor.cpp
+++ b/tools/aapt2/xml/XmlActionExecutor.cpp
@@ -19,8 +19,7 @@
 namespace aapt {
 namespace xml {
 
-static bool wrapper_one(XmlNodeAction::ActionFunc& f, Element* el,
-                        SourcePathDiagnostics*) {
+static bool wrapper_one(XmlNodeAction::ActionFunc& f, Element* el, SourcePathDiagnostics*) {
   return f(el);
 }
 
@@ -47,8 +46,8 @@
   *msg << el->name << ">";
 }
 
-bool XmlNodeAction::Execute(XmlActionExecutorPolicy policy,
-                            SourcePathDiagnostics* diag, Element* el) const {
+bool XmlNodeAction::Execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
+                            Element* el) const {
   bool error = false;
   for (const ActionFuncWithDiag& action : actions_) {
     error |= !action(el, diag);
@@ -56,28 +55,27 @@
 
   for (Element* child_el : el->GetChildElements()) {
     if (child_el->namespace_uri.empty()) {
-      std::map<std::string, XmlNodeAction>::const_iterator iter =
-          map_.find(child_el->name);
+      std::map<std::string, XmlNodeAction>::const_iterator iter = map_.find(child_el->name);
       if (iter != map_.end()) {
         error |= !iter->second.Execute(policy, diag, child_el);
         continue;
       }
-    }
 
-    if (policy == XmlActionExecutorPolicy::kWhitelist) {
-      DiagMessage error_msg(child_el->line_number);
-      error_msg << "unknown element ";
-      PrintElementToDiagMessage(child_el, &error_msg);
-      error_msg << " found";
-      diag->Error(error_msg);
-      error = true;
+      if (policy == XmlActionExecutorPolicy::kWhitelist) {
+        DiagMessage error_msg(child_el->line_number);
+        error_msg << "unknown element ";
+        PrintElementToDiagMessage(child_el, &error_msg);
+        error_msg << " found";
+        diag->Error(error_msg);
+        error = true;
+      }
     }
   }
   return !error;
 }
 
-bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy,
-                                IDiagnostics* diag, XmlResource* doc) const {
+bool XmlActionExecutor::Execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
+                                XmlResource* doc) const {
   SourcePathDiagnostics source_diag(doc->file.source, diag);
 
   Element* el = FindRootElement(doc);
@@ -90,20 +88,19 @@
   }
 
   if (el->namespace_uri.empty()) {
-    std::map<std::string, XmlNodeAction>::const_iterator iter =
-        map_.find(el->name);
+    std::map<std::string, XmlNodeAction>::const_iterator iter = map_.find(el->name);
     if (iter != map_.end()) {
       return iter->second.Execute(policy, &source_diag, el);
     }
-  }
 
-  if (policy == XmlActionExecutorPolicy::kWhitelist) {
-    DiagMessage error_msg(el->line_number);
-    error_msg << "unknown element ";
-    PrintElementToDiagMessage(el, &error_msg);
-    error_msg << " found";
-    source_diag.Error(error_msg);
-    return false;
+    if (policy == XmlActionExecutorPolicy::kWhitelist) {
+      DiagMessage error_msg(el->line_number);
+      error_msg << "unknown element ";
+      PrintElementToDiagMessage(el, &error_msg);
+      error_msg << " found";
+      source_diag.Error(error_msg);
+      return false;
+    }
   }
   return true;
 }
diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h
index 68e3563..1d70045 100644
--- a/tools/aapt2/xml/XmlActionExecutor.h
+++ b/tools/aapt2/xml/XmlActionExecutor.h
@@ -31,17 +31,12 @@
 namespace xml {
 
 enum class XmlActionExecutorPolicy {
-  /**
-   * Actions on run if elements are matched, errors occur only when actions
-   * return false.
-   */
+  // Actions are run if elements are matched, errors occur only when actions return false.
   kNone,
 
-  /**
-   * The actions defined must match and run. If an element is found that does
-   * not match
-   * an action, an error occurs.
-   */
+  // The actions defined must match and run. If an element is found that does
+  // not match an action, an error occurs.
+  // Note: namespaced elements are always ignored.
   kWhitelist,
 };
 
@@ -52,14 +47,12 @@
  */
 class XmlNodeAction {
  public:
-  using ActionFuncWithDiag =
-      std::function<bool(Element*, SourcePathDiagnostics*)>;
+  using ActionFuncWithDiag = std::function<bool(Element*, SourcePathDiagnostics*)>;
   using ActionFunc = std::function<bool(Element*)>;
 
   /**
    * Find or create a child XmlNodeAction that will be performed for the child
-   * element
-   * with the name `name`.
+   * element with the name `name`.
    */
   XmlNodeAction& operator[](const std::string& name) { return map_[name]; }
 
@@ -72,8 +65,7 @@
  private:
   friend class XmlActionExecutor;
 
-  bool Execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag,
-               Element* el) const;
+  bool Execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, Element* el) const;
 
   std::map<std::string, XmlNodeAction> map_;
   std::vector<ActionFuncWithDiag> actions_;
@@ -98,8 +90,7 @@
    * Execute the defined actions for this XmlResource.
    * Returns true if all actions return true, otherwise returns false.
    */
-  bool Execute(XmlActionExecutorPolicy policy, IDiagnostics* diag,
-               XmlResource* doc) const;
+  bool Execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, XmlResource* doc) const;
 
  private:
   std::map<std::string, XmlNodeAction> map_;
diff --git a/tools/layoutlib/.gitignore b/tools/layoutlib/.gitignore
deleted file mode 100644
index a2b0c33..0000000
--- a/tools/layoutlib/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-bin
-/.idea/workspace.xml
-/out
-/bridge/out
-/.idea/kotlinc.xml
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/.name b/tools/layoutlib/.idea/.name
deleted file mode 100644
index 10eb5c1..0000000
--- a/tools/layoutlib/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-layoutlib
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
deleted file mode 100644
index 0450be3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_jar</output-path>
-    <root id="archive" name="studio-android-widgets.jar">
-      <element id="module-output" name="studio-android-widgets" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml b/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
deleted file mode 100644
index a844ca3..0000000
--- a/tools/layoutlib/.idea/artifacts/studio_android_widgets_src_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets-src:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_src_jar</output-path>
-    <root id="archive" name="studio-android-widgets-src.jar">
-      <element id="dir-copy" path="$PROJECT_DIR$/studio-custom-widgets/src" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml
deleted file mode 100644
index ac90d1e..0000000
--- a/tools/layoutlib/.idea/codeStyleSettings.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectCodeStyleSettingsManager">
-    <option name="PER_PROJECT_SETTINGS">
-      <value>
-        <option name="FIELD_NAME_PREFIX" value="m" />
-        <option name="STATIC_FIELD_NAME_PREFIX" value="s" />
-        <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
-        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
-        <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
-          <value />
-        </option>
-        <option name="IMPORT_LAYOUT_TABLE">
-          <value>
-            <package name="com.android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="org" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="android" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="java" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="false" />
-            <emptyLine />
-            <package name="" withSubpackages="true" static="true" />
-          </value>
-        </option>
-        <option name="RIGHT_MARGIN" value="100" />
-        <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
-        <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
-        <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
-        <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
-        <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
-        <option name="WRAP_COMMENTS" value="true" />
-        <JavaCodeStyleSettings>
-          <option name="CLASS_NAMES_IN_JAVADOC" value="3" />
-        </JavaCodeStyleSettings>
-        <XML>
-          <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
-        </XML>
-        <codeStyleSettings language="JAVA">
-          <option name="KEEP_LINE_BREAKS" value="false" />
-          <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
-          <option name="CALL_PARAMETERS_WRAP" value="1" />
-          <option name="METHOD_PARAMETERS_WRAP" value="1" />
-          <option name="THROWS_LIST_WRAP" value="1" />
-          <option name="EXTENDS_KEYWORD_WRAP" value="1" />
-          <option name="THROWS_KEYWORD_WRAP" value="1" />
-          <option name="BINARY_OPERATION_WRAP" value="1" />
-          <option name="TERNARY_OPERATION_WRAP" value="1" />
-          <option name="ARRAY_INITIALIZER_WRAP" value="1" />
-          <option name="ASSIGNMENT_WRAP" value="1" />
-          <option name="ASSERT_STATEMENT_WRAP" value="1" />
-          <option name="IF_BRACE_FORCE" value="3" />
-          <option name="DOWHILE_BRACE_FORCE" value="3" />
-          <option name="WHILE_BRACE_FORCE" value="3" />
-          <option name="FOR_BRACE_FORCE" value="3" />
-          <option name="WRAP_LONG_LINES" value="true" />
-          <arrangement>
-            <groups>
-              <group>
-                <type>GETTERS_AND_SETTERS</type>
-                <order>KEEP</order>
-              </group>
-              <group>
-                <type>OVERRIDDEN_METHODS</type>
-                <order>KEEP</order>
-              </group>
-            </groups>
-          </arrangement>
-        </codeStyleSettings>
-        <codeStyleSettings language="XML">
-          <indentOptions>
-            <option name="CONTINUATION_INDENT_SIZE" value="4" />
-          </indentOptions>
-        </codeStyleSettings>
-      </value>
-    </option>
-    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/compiler.xml b/tools/layoutlib/.idea/compiler.xml
deleted file mode 100644
index 35961a2..0000000
--- a/tools/layoutlib/.idea/compiler.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CompilerConfiguration">
-    <option name="DEFAULT_COMPILER" value="Javac" />
-    <excludeFromCompile>
-      <directory url="file://$PROJECT_DIR$/create/tests/mock_data" includeSubdirectories="true" />
-    </excludeFromCompile>
-    <resourceExtensions />
-    <wildcardResourcePatterns>
-      <entry name="!?*.java" />
-      <entry name="!?*.form" />
-      <entry name="!?*.class" />
-      <entry name="!?*.groovy" />
-      <entry name="!?*.scala" />
-      <entry name="!?*.flex" />
-      <entry name="!?*.kt" />
-      <entry name="!?*.clj" />
-    </wildcardResourcePatterns>
-    <annotationProcessing>
-      <profile default="true" name="Default" enabled="false">
-        <processorPath useClasspath="true" />
-      </profile>
-    </annotationProcessing>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/Android.xml b/tools/layoutlib/.idea/copyright/Android.xml
deleted file mode 100644
index d81d75d..0000000
--- a/tools/layoutlib/.idea/copyright/Android.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="CopyrightManager">
-  <copyright>
-    <option name="notice" value="Copyright (C) &amp;#36;today.year The Android Open Source Project&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;     http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
-    <option name="keyword" value="Copyright" />
-    <option name="allowReplaceKeyword" value="" />
-    <option name="myName" value="Android" />
-    <option name="myLocal" value="true" />
-  </copyright>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/copyright/profiles_settings.xml b/tools/layoutlib/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index 20145de..0000000
--- a/tools/layoutlib/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<component name="CopyrightManager">
-  <settings default="Android" />
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/encodings.xml b/tools/layoutlib/.idea/encodings.xml
deleted file mode 100644
index f758959..0000000
--- a/tools/layoutlib/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
-    <file url="PROJECT" charset="UTF-8" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml b/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 74fa549..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0" is_locked="false">
-    <option name="myName" value="Project Default" />
-    <option name="myLocal" value="false" />
-    <inspection_tool class="DefaultFileTemplate" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="CHECK_FILE_HEADER" value="true" />
-      <option name="CHECK_TRY_CATCH_SECTION" value="true" />
-      <option name="CHECK_METHOD_BODY" value="true" />
-    </inspection_tool>
-    <inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
-      <option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
-      <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
-    </inspection_tool>
-    <inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="false" />
-      <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
-      <option name="SUGGEST_PRIVATE_FOR_INNERS" value="true" />
-    </inspection_tool>
-  </profile>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml b/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 3b31283..0000000
--- a/tools/layoutlib/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="PROJECT_PROFILE" value="Project Default" />
-    <option name="USE_PROJECT_PROFILE" value="true" />
-    <version value="1.0" />
-  </settings>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/framework_jar.xml b/tools/layoutlib/.idea/libraries/framework_jar.xml
deleted file mode 100644
index 6695a36..0000000
--- a/tools/layoutlib/.idea/libraries/framework_jar.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<component name="libraryTable">
-  <library name="framework.jar">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../core/java" />
-      <root url="file://$PROJECT_DIR$/../../graphics/java" />
-      <root url="file://$PROJECT_DIR$/../../../../libcore/luni/src/main/java" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/junit.xml b/tools/layoutlib/.idea/libraries/junit.xml
deleted file mode 100644
index ba46ebf..0000000
--- a/tools/layoutlib/.idea/libraries/junit.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="junit">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/junit-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="file://$PROJECT_DIR$/../../../../external/junit/src" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml b/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
deleted file mode 100644
index a873600..0000000
--- a/tools/layoutlib/.idea/libraries/layoutlib_api_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
-  <library name="layoutlib_api-prebuilt">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES>
-      <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/layoutlib_api/layoutlib_api-sources.jar!/" />
-    </SOURCES>
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/mockito.xml b/tools/layoutlib/.idea/libraries/mockito.xml
deleted file mode 100644
index 032963e..0000000
--- a/tools/layoutlib/.idea/libraries/mockito.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="mockito">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/mockito-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/objenesis.xml b/tools/layoutlib/.idea/libraries/objenesis.xml
deleted file mode 100644
index 1484de5..0000000
--- a/tools/layoutlib/.idea/libraries/objenesis.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<component name="libraryTable">
-  <library name="objenesis">
-    <CLASSES>
-      <root url="jar://$PROJECT_DIR$/../../../../out/host/common/obj/JAVA_LIBRARIES/objenesis-host_intermediates/javalib.jar!/" />
-    </CLASSES>
-    <JAVADOC />
-    <SOURCES />
-  </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/misc.xml b/tools/layoutlib/.idea/misc.xml
deleted file mode 100644
index 44b47f2..0000000
--- a/tools/layoutlib/.idea/misc.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="EntryPointsManager">
-    <entry_points version="2.0" />
-    <list size="1">
-      <item index="0" class="java.lang.String" itemvalue="com.android.tools.layoutlib.annotations.LayoutlibDelegate" />
-    </list>
-  </component>
-  <component name="FrameworkDetectionExcludesConfiguration">
-    <type id="android" />
-  </component>
-  <component name="NullableNotNullManager">
-    <option name="myDefaultNullable" value="android.annotation.Nullable" />
-    <option name="myDefaultNotNull" value="android.annotation.NonNull" />
-    <option name="myNullables">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.Nullable" />
-        </list>
-      </value>
-    </option>
-    <option name="myNotNulls">
-      <value>
-        <list size="6">
-          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
-          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
-          <item index="4" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
-          <item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
-        </list>
-      </value>
-    </option>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/out" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/modules.xml b/tools/layoutlib/.idea/modules.xml
deleted file mode 100644
index 6ffc1cc..0000000
--- a/tools/layoutlib/.idea/modules.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/bridge/bridge.iml" filepath="$PROJECT_DIR$/bridge/bridge.iml" />
-      <module fileurl="file://$PROJECT_DIR$/create/create.iml" filepath="$PROJECT_DIR$/create/create.iml" />
-      <module fileurl="file://$PROJECT_DIR$/legacy/legacy.iml" filepath="$PROJECT_DIR$/legacy/legacy.iml" />
-      <module fileurl="file://$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" filepath="$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml b/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
deleted file mode 100644
index 0b22717..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_bridge.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in bridge" type="JUnit" factoryName="JUnit" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml b/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
deleted file mode 100644
index b9cd419d..0000000
--- a/tools/layoutlib/.idea/runConfigurations/All_in_create.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="All in create" type="JUnit" factoryName="JUnit" singleton="false" nameIsGenerated="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="create" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" value="" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="package" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml b/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
deleted file mode 100644
index b402849..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Bridge_quick.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Bridge quick" type="JUnit" factoryName="JUnit">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <module name="bridge" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="PACKAGE_NAME" />
-    <option name="MAIN_CLASS_NAME" value="" />
-    <option name="METHOD_NAME" value="" />
-    <option name="TEST_OBJECT" value="pattern" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PARAMETERS" value="" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <option name="TEST_SEARCH_SCOPE">
-      <value defaultName="singleModule" />
-    </option>
-    <envs />
-    <patterns>
-      <pattern testClass="com.android.layoutlib.bridge.TestDelegates" />
-      <pattern testClass="android.graphics.Matrix_DelegateTest" />
-      <pattern testClass="com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest" />
-    </patterns>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
diff --git a/tools/layoutlib/.idea/runConfigurations/Create.xml b/tools/layoutlib/.idea/runConfigurations/Create.xml
deleted file mode 100644
index 536a23f..0000000
--- a/tools/layoutlib/.idea/runConfigurations/Create.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="Create" type="Application" factoryName="Application" singleton="true">
-    <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
-    <option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
-    <option name="VM_PARAMETERS" value="-ea" />
-    <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icudata-host-jarjar_intermediates/classes-jarjar.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-host-jarjar_intermediates/classes-jarjar.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
-    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../../../../" />
-    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
-    <option name="ALTERNATIVE_JRE_PATH" value="" />
-    <option name="ENABLE_SWING_INSPECTOR" value="false" />
-    <option name="ENV_VARIABLES" />
-    <option name="PASS_PARENT_ENVS" value="true" />
-    <module name="create" />
-    <envs />
-    <RunnerSettings RunnerId="Debug">
-      <option name="DEBUG_PORT" value="" />
-      <option name="TRANSPORT" value="0" />
-      <option name="LOCAL" value="true" />
-    </RunnerSettings>
-    <RunnerSettings RunnerId="Run" />
-    <ConfigurationWrapper RunnerId="Debug" />
-    <ConfigurationWrapper RunnerId="Run" />
-    <method />
-  </configuration>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/scopes/scope_settings.xml b/tools/layoutlib/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 922003b..0000000
--- a/tools/layoutlib/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<component name="DependencyValidationManager">
-  <state>
-    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
-  </state>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/uiDesigner.xml b/tools/layoutlib/.idea/uiDesigner.xml
deleted file mode 100644
index 3b00020..0000000
--- a/tools/layoutlib/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Palette2">
-    <group name="Swing">
-      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
-      </item>
-      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
-        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
-        <initial-values>
-          <property name="text" value="Button" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="RadioButton" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="CheckBox" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
-        <initial-values>
-          <property name="text" value="Label" />
-        </initial-values>
-      </item>
-      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
-          <preferred-size width="150" height="-1" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
-          <preferred-size width="150" height="50" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
-          <preferred-size width="200" height="200" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
-      </item>
-      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
-      </item>
-      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
-          <preferred-size width="-1" height="20" />
-        </default-constraints>
-      </item>
-      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
-      </item>
-      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
-        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
-      </item>
-    </group>
-  </component>
-</project>
-
diff --git a/tools/layoutlib/.idea/vcs.xml b/tools/layoutlib/.idea/vcs.xml
deleted file mode 100644
index 9ab281a..0000000
--- a/tools/layoutlib/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
-  </component>
-</project>
-
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
deleted file mode 100644
index 29c933a..0000000
--- a/tools/layoutlib/Android.mk
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(my-dir)
-include $(CLEAR_VARS)
-
-#
-# Define rules to build temp_layoutlib.jar, which contains a subset of
-# the classes in framework.jar.  The layoutlib_create tool is used to
-# transform the framework jar into the temp_layoutlib jar.
-#
-
-# We need to process the framework classes.jar file, but we can't
-# depend directly on it (private vars won't be inherited correctly).
-# So, we depend on framework's BUILT file.
-built_framework_dep := $(call java-lib-deps,framework)
-built_framework_classes := $(call java-lib-files,framework)
-
-built_oj_dep := $(call java-lib-deps,core-oj)
-built_oj_classes := $(call java-lib-files,core-oj)
-
-built_core_dep := $(call java-lib-deps,core-libart)
-built_core_classes := $(call java-lib-files,core-libart)
-
-built_ext_dep := $(call java-lib-deps,ext)
-built_ext_classes := $(call java-lib-files,ext)
-
-built_icudata_dep := $(call java-lib-deps,icu4j-icudata-host-jarjar,HOST)
-built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-host-jarjar,HOST)
-
-built_layoutlib_create_jar := $(call java-lib-files,layoutlib_create,HOST)
-
-# This is mostly a copy of config/host_java_library.mk
-LOCAL_MODULE := temp_layoutlib
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_BUILT_MODULE_STEM := classes.jar
-
-#######################################
-include $(BUILD_SYSTEM)/base_rules.mk
-#######################################
-
-$(LOCAL_BUILT_MODULE): $(built_oj_dep) \
-                       $(built_core_dep) \
-                       $(built_framework_dep) \
-                       $(built_ext_dep) \
-		       $(built_icudata_dep) \
-		       $(built_icutzdata_dep) \
-                       $(built_layoutlib_create_jar)
-	$(hide) echo "host layoutlib_create: $@"
-	$(hide) mkdir -p $(dir $@)
-	$(hide) rm -f $@
-	$(hide) ls -l $(built_framework_classes)
-	$(hide) java -ea -jar $(built_layoutlib_create_jar) \
-	             $@ \
-	             $(built_oj_classes) \
-	             $(built_core_classes) \
-	             $(built_framework_classes) \
-	             $(built_ext_classes) \
-		     $(built_icudata_dep) \
-		     $(built_icutzdata_dep) \
-	             $(built_ext_data)
-	$(hide) ls -l $(built_framework_classes)
-
-
-#
-# Include the subdir makefiles.
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/README b/tools/layoutlib/README
deleted file mode 100644
index 0fea9bd..0000000
--- a/tools/layoutlib/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Layoutlib is a custom version of the android View framework designed to run inside Eclipse.
-The goal of the library is to provide layout rendering in Eclipse that are very very close to their rendering on devices.
-
-None of the com.android.* or android.* classes in layoutlib run on devices.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
deleted file mode 100644
index 9c4160c..0000000
--- a/tools/layoutlib/bridge/.classpath
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
-	<classpathentry kind="src" path="tests/src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/sdk-common/sdk-common.jar"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/guavalib_intermediates/javalib.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/.project b/tools/layoutlib/bridge/.project
deleted file mode 100644
index e36e71b..0000000
--- a/tools/layoutlib/bridge/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/.settings/README.txt b/tools/layoutlib/bridge/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/bridge/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/bridge/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
deleted file mode 100644
index 3dd8002..0000000
--- a/tools/layoutlib/bridge/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt \
-	tools-common-prebuilt
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	temp_layoutlib \
-	ninepatch-prebuilt
-
-LOCAL_MODULE := layoutlib
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
deleted file mode 100644
index 85ec3eb..0000000
--- a/tools/layoutlib/bridge/bridge.iml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-      <excludeFolder url="file://$MODULE_DIR$/bin" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.idea" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/generated" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/assets" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/dependency-cache" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/incremental" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/libs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/manifests" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/res" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/rs" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/symbols" />
-      <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/gradle" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="module-library">
-      <library name="ninepatch-prebuilt">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library">
-      <library name="tools-common-prebuilt">
-        <ANNOTATIONS>
-          <root url="file://$MODULE_DIR$/.." />
-        </ANNOTATIONS>
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module-library" scope="TEST">
-      <library name="kxml2-2.3.0">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="guava">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="module-library" scope="TEST">
-      <library name="sdk-common">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-    <orderEntry type="library" scope="TEST" name="mockito" level="project" />
-    <orderEntry type="library" scope="TEST" name="objenesis" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/resources/bars/README b/tools/layoutlib/bridge/resources/bars/README
deleted file mode 100644
index c84ef80..0000000
--- a/tools/layoutlib/bridge/resources/bars/README
+++ /dev/null
@@ -1,8 +0,0 @@
-The directory contains the resources for StatusBar and Navigation Bar.
-
-The resources are not arranged as per the standard resources configuration.
-They are stored per API. However, to prevent duplication of resources, each API
-resource directory is used as a backup for all earlier API levels.
-
-For example, for the back icon for ICS, we search first in v18, where we don't
-find it, and then in v19.
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
deleted file mode 100644
index 55bd1d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
deleted file mode 100644
index e208a0d..0000000
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar600dp.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2015 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-		  	android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:visibility="invisible"/>
-	<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:scaleType="centerInside"/>
-	<View
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:visibility="invisible"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/status_bar.xml b/tools/layoutlib/bridge/resources/bars/status_bar.xml
deleted file mode 100644
index 04571e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/status_bar.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"/>
-    <!-- The exact size of the wifi icon is specified in order to scale it properly.
-    Without scaling, it appeared huge. This is currently, 70% of the actual size. -->
-    <ImageView
-            android:layout_height="22.4dp"
-            android:layout_width="20.65dp"
-            android:layout_marginTop="1dp"/>
-    <ImageView
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_marginLeft="3dp"
-            android:layout_marginRight="5dp"
-            android:layout_marginTop="4dp"/>
-    <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="4dp"
-            android:layout_marginRight="5dp"
-            android:gravity="center_vertical"
-            android:textSize="16dp"
-            android:fontFamily="sans-serif-medium"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
deleted file mode 100644
index 76d78d9..0000000
--- a/tools/layoutlib/bridge/resources/bars/title_bar.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-	<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"/>
-</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index c920ec4..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 943332e..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 36c61e1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v18/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
deleted file mode 100644
index 84e6bc8..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
deleted file mode 100644
index 38e4f45..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index bf9f300..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 6248cfd..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 782ebfe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 677b471..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index a1b8062..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index fcdbefe..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 633d864..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 4665e2a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/ldrtl-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
deleted file mode 100644
index a00bc5b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
deleted file mode 100644
index dc3183b..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index b07f611..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 441de0c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index bd60cd6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index c5bc5c9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index f621d9c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 459a1a2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 79cfcee..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 64f6a22..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6e0b071..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 494b005..0000000
--- a/tools/layoutlib/bridge/resources/bars/v19/xxhdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
deleted file mode 100644
index d2760bb..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
deleted file mode 100644
index df43e21..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
deleted file mode 100644
index 6fab1d6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index f17189a..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 2fcfdde..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 48708a5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 3d73184..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 786935d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
deleted file mode 100644
index 1d8c3af..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
deleted file mode 100644
index 66de0ec..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 30c65f5..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 2a9757d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
deleted file mode 100644
index a356285..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
deleted file mode 100644
index ba2d0b2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 94a74b1..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 555bcd9..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
deleted file mode 100644
index 0498b6c..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/stat_sys_wifi_signal_4_fully.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="32.0dp"
-        android:height="29.5dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
-</vector>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 29da099..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 59b32f2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ba66d27..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 6474aad..0000000
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index 754cdf6..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index b5326d2..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/hdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
deleted file mode 100644
index 7023ea7..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/ldpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 17a955d..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
deleted file mode 100644
index 19165ab..0000000
--- a/tools/layoutlib/bridge/resources/bars/v9/mdpi/stat_sys_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-b.png b/tools/layoutlib/bridge/resources/icons/shadow-b.png
deleted file mode 100644
index 68f4f4b..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-bl.png b/tools/layoutlib/bridge/resources/icons/shadow-bl.png
deleted file mode 100644
index ee7dbe8..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-br.png b/tools/layoutlib/bridge/resources/icons/shadow-br.png
deleted file mode 100644
index c45ad77..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-l.png b/tools/layoutlib/bridge/resources/icons/shadow-l.png
deleted file mode 100644
index 77d0bd0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-r.png b/tools/layoutlib/bridge/resources/icons/shadow-r.png
deleted file mode 100644
index 4af7a33..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tl.png b/tools/layoutlib/bridge/resources/icons/shadow-tl.png
deleted file mode 100644
index 424fb36..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow-tr.png b/tools/layoutlib/bridge/resources/icons/shadow-tr.png
deleted file mode 100644
index 1fd0c772..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-b.png b/tools/layoutlib/bridge/resources/icons/shadow2-b.png
deleted file mode 100644
index 963973e..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-b.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png b/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
deleted file mode 100644
index 7612487..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-bl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-br.png b/tools/layoutlib/bridge/resources/icons/shadow2-br.png
deleted file mode 100644
index 8e20252..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-br.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-l.png b/tools/layoutlib/bridge/resources/icons/shadow2-l.png
deleted file mode 100644
index 2db18a0..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-l.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-r.png b/tools/layoutlib/bridge/resources/icons/shadow2-r.png
deleted file mode 100644
index 8e026f1..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-r.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png b/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
deleted file mode 100644
index a8045ed..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tl.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png b/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
deleted file mode 100644
index 590373c..0000000
--- a/tools/layoutlib/bridge/resources/icons/shadow2-tr.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
deleted file mode 100644
index ce2aec79..0000000
--- a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-
-import android.os.Handler;
-import android.os.Handler_Delegate;
-import android.os.Message;
-
-import java.util.PriorityQueue;
-import java.util.Queue;
-
-/**
- * Abstract animation thread.
- * <p/>
- * This does not actually start an animation, instead it fakes a looper that will play whatever
- * animation is sending messages to its own {@link Handler}.
- * <p/>
- * Classes should implement {@link #preAnimation()} and {@link #postAnimation()}.
- * <p/>
- * If {@link #preAnimation()} does not start an animation somehow then the thread doesn't do
- * anything.
- *
- */
-public abstract class AnimationThread extends Thread {
-
-    private static class MessageBundle implements Comparable<MessageBundle> {
-        final Handler mTarget;
-        final Message mMessage;
-        final long mUptimeMillis;
-
-        MessageBundle(Handler target, Message message, long uptimeMillis) {
-            mTarget = target;
-            mMessage = message;
-            mUptimeMillis = uptimeMillis;
-        }
-
-        @Override
-        public int compareTo(MessageBundle bundle) {
-            if (mUptimeMillis < bundle.mUptimeMillis) {
-                return -1;
-            }
-            return 1;
-        }
-    }
-
-    private final RenderSessionImpl mSession;
-
-    private Queue<MessageBundle> mQueue = new PriorityQueue<MessageBundle>();
-    private final IAnimationListener mListener;
-
-    public AnimationThread(RenderSessionImpl scene, String threadName,
-            IAnimationListener listener) {
-        super(threadName);
-        mSession = scene;
-        mListener = listener;
-    }
-
-    public abstract Result preAnimation();
-    public abstract void postAnimation();
-
-    @Override
-    public void run() {
-        Bridge.prepareThread();
-        try {
-            /* FIXME: The ANIMATION_FRAME message no longer exists.  Instead, the
-             * animation timing loop is completely based on a Choreographer objects
-             * that schedules animation and drawing frames.  The animation handler is
-             * no longer even a handler; it is just a Runnable enqueued on the Choreographer.
-            Handler_Delegate.setCallback(new IHandlerCallback() {
-                @Override
-                public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-                    if (msg.what == ValueAnimator.ANIMATION_START ||
-                            msg.what == ValueAnimator.ANIMATION_FRAME) {
-                        mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
-                    } else {
-                        // just ignore.
-                    }
-                }
-            });
-            */
-
-            // call out to the pre-animation work, which should start an animation or more.
-            Result result = preAnimation();
-            if (result.isSuccess() == false) {
-                mListener.done(result);
-            }
-
-            // loop the animation
-            RenderSession session = mSession.getSession();
-            do {
-                // check early.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // get the next message.
-                MessageBundle bundle = mQueue.poll();
-                if (bundle == null) {
-                    break;
-                }
-
-                // sleep enough for this bundle to be on time
-                long currentTime = System.currentTimeMillis();
-                if (currentTime < bundle.mUptimeMillis) {
-                    try {
-                        sleep(bundle.mUptimeMillis - currentTime);
-                    } catch (InterruptedException e) {
-                        // FIXME log/do something/sleep again?
-                        e.printStackTrace();
-                    }
-                }
-
-                // check after sleeping.
-                if (mListener.isCanceled()) {
-                    break;
-                }
-
-                // ready to do the work, acquire the scene.
-                result = mSession.acquire(250);
-                if (result.isSuccess() == false) {
-                    mListener.done(result);
-                    return;
-                }
-
-                // process the bundle. If the animation is not finished, this will enqueue
-                // the next message, so mQueue will have another one.
-                try {
-                    // check after acquiring in case it took a while.
-                    if (mListener.isCanceled()) {
-                        break;
-                    }
-
-                    bundle.mTarget.handleMessage(bundle.mMessage);
-                    if (mSession.render(false /*freshRender*/).isSuccess()) {
-                        mListener.onNewFrame(session);
-                    }
-                } finally {
-                    mSession.release();
-                }
-            } while (mListener.isCanceled() == false && mQueue.size() > 0);
-
-            mListener.done(Status.SUCCESS.createResult());
-
-        } catch (Throwable throwable) {
-            // can't use Bridge.getLog() as the exception might be thrown outside
-            // of an acquire/release block.
-            mListener.done(Status.ERROR_UNKNOWN.createResult("Error playing animation", throwable));
-
-        } finally {
-            postAnimation();
-            Handler_Delegate.setCallback(null);
-            Bridge.cleanupThread();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
deleted file mode 100644
index 28a489a..0000000
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.animation;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.animation.PropertyValuesHolder
- *
- * Through the layoutlib_create tool, the original native methods of PropertyValuesHolder have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- * The main goal of this class' methods are to provide a native way to access setters and getters
- * on some object. We override these methods to use reflection since the original reflection
- * implementation of the PropertyValuesHolder won't be able to access protected methods.
- *
- */
-/*package*/
-@SuppressWarnings("unused")
-class PropertyValuesHolder_Delegate {
-    // This code is copied from android.animation.PropertyValuesHolder and must be kept in sync
-    // We try several different types when searching for appropriate setter/getter functions.
-    // The caller may have supplied values in a type that does not match the setter/getter
-    // functions (such as the integers 0 and 1 to represent floating point values for alpha).
-    // Also, the use of generics in constructors means that we end up with the Object versions
-    // of primitive types (Float vs. float). But most likely, the setter/getter functions
-    // will take primitive types instead.
-    // So we supply an ordered array of other types to try before giving up.
-    private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class,
-            Double.class, Integer.class};
-    private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class,
-            Float.class, Double.class};
-
-    private static final Object sMethodIndexLock = new Object();
-    private static final Map<Long, Method> ID_TO_METHOD = new HashMap<Long, Method>();
-    private static final Map<String, Long> METHOD_NAME_TO_ID = new HashMap<String, Long>();
-    private static long sNextId = 1;
-
-    private static long registerMethod(Class<?> targetClass, String methodName, Class[] types,
-            int nArgs) {
-        // Encode the number of arguments in the method name
-        String methodIndexName = String.format("%1$s.%2$s#%3$d", targetClass.getSimpleName(),
-                methodName, nArgs);
-        synchronized (sMethodIndexLock) {
-            Long methodId = METHOD_NAME_TO_ID.get(methodIndexName);
-
-            if (methodId != null) {
-                // The method was already registered
-                return methodId;
-            }
-
-            Class[] args = new Class[nArgs];
-            Method method = null;
-            for (Class typeVariant : types) {
-                for (int i = 0; i < nArgs; i++) {
-                    args[i] = typeVariant;
-                }
-                try {
-                    method = targetClass.getDeclaredMethod(methodName, args);
-                } catch (NoSuchMethodException ignore) {
-                }
-            }
-
-            if (method != null) {
-                methodId = sNextId++;
-                ID_TO_METHOD.put(methodId, method);
-                METHOD_NAME_TO_ID.put(methodIndexName, methodId);
-
-                return methodId;
-            }
-        }
-
-        // Method not found
-        return 0;
-    }
-
-    private static void callMethod(Object target, long methodID, Object... args) {
-        Method method = ID_TO_METHOD.get(methodID);
-        assert method != null;
-
-        try {
-            method.setAccessible(true);
-            method.invoke(target, args);
-        } catch (IllegalAccessException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        } catch (InvocationTargetException e) {
-            Bridge.getLog().error(null, "Unable to update property during animation", e, null);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetIntMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleIntMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetFloatMethod(Class<?> targetClass, String methodName) {
-        return nGetMultipleFloatMethod(targetClass, methodName, 1);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, INTEGER_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName,
-            int numParams) {
-        return registerMethod(targetClass, methodName, FLOAT_VARIANTS, numParams);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) {
-        callMethod(target, methodID, arg);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1,
-            int arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1,
-            int arg2, int arg3, int arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleIntMethod(Object target, long methodID,
-            int[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1,
-            float arg2) {
-        callMethod(target, methodID, arg1, arg2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1,
-            float arg2, float arg3, float arg4) {
-        callMethod(target, methodID, arg1, arg2, arg3, arg4);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID,
-            float[] args) {
-        assert args != null;
-
-        // Box parameters
-        Object[] params = new Object[args.length];
-        for (int i = 0; i < args.length; i++) {
-            params[i] = args;
-        }
-        callMethod(target, methodID, params);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java b/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
deleted file mode 100644
index f7654ce..0000000
--- a/tools/layoutlib/bridge/src/android/app/Fragment_Delegate.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Bundle;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Fragment}
- *
- * Through the layoutlib_create tool, the original  methods of Fragment have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * The methods being re-implemented are the ones responsible for instantiating Fragment objects.
- * Because the classes of these objects are found in the project, these methods need access to
- * {@link LayoutlibCallback} object. They are however static methods, so the callback is set
- * before the inflation through {@link #setLayoutlibCallback(LayoutlibCallback)}.
- */
-public class Fragment_Delegate {
-
-    private static LayoutlibCallback sLayoutlibCallback;
-
-    /**
-     * Sets the current {@link LayoutlibCallback} to be used to instantiate classes coming
-     * from the project being rendered.
-     */
-    public static void setLayoutlibCallback(LayoutlibCallback layoutlibCallback) {
-        sLayoutlibCallback = layoutlibCallback;
-    }
-
-    /**
-     * Like {@link #instantiate(Context, String, Bundle)} but with a null
-     * argument Bundle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname) {
-        return instantiate(context, fname, null);
-    }
-
-    /**
-     * Create a new instance of a Fragment with the given class name.  This is
-     * the same as calling its empty constructor.
-     *
-     * @param context The calling context being used to instantiate the fragment.
-     * This is currently just used to get its ClassLoader.
-     * @param fname The class name of the fragment to instantiate.
-     * @param args Bundle of arguments to supply to the fragment, which it
-     * can retrieve with {@link Fragment#getArguments()}.  May be null.
-     * @return Returns a new fragment instance.
-     * @throws Fragment.InstantiationException If there is a failure in instantiating
-     * the given fragment class.  This is a runtime exception; it is not
-     * normally expected to happen.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Fragment instantiate(Context context, String fname, Bundle args) {
-        try {
-            if (sLayoutlibCallback != null) {
-                Fragment f = (Fragment) sLayoutlibCallback.loadView(fname,
-                        new Class[0], new Object[0]);
-
-                if (args != null) {
-                    args.setClassLoader(f.getClass().getClassLoader());
-                    f.mArguments = args;
-                }
-                return f;
-            }
-
-            return null;
-        } catch (ClassNotFoundException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (java.lang.InstantiationException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (IllegalAccessException e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        } catch (Exception e) {
-            throw new Fragment.InstantiationException("Unable to instantiate fragment " + fname
-                    + ": make sure class name exists, is public, and has an"
-                    + " empty constructor that is public", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java b/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
deleted file mode 100644
index 591aee0..0000000
--- a/tools/layoutlib/bridge/src/android/app/SystemServiceRegistry_Accessor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-/**
- * Class to allow accessing {@link SystemServiceRegistry#getSystemServiceName}
- */
-public class SystemServiceRegistry_Accessor {
-    /**
-     * Gets the name of the system-level service that is represented by the specified class.
-     */
-    public static String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry.getSystemServiceName(serviceClass);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
deleted file mode 100644
index b4d5288..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/AssetManager_Delegate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.SparseArray;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link AssetManager}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of AssetManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AssetManager_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static long newTheme(AssetManager manager) {
-        return Resources_Theme_Delegate.getDelegateManager()
-                .addNewDelegate(new Resources_Theme_Delegate());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void deleteTheme(AssetManager manager, long theme) {
-        Resources_Theme_Delegate.getDelegateManager().removeJavaReferenceFor(theme);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static SparseArray<String> getAssignedPackageIdentifiers(AssetManager manager) {
-        return new SparseArray<>();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java b/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
deleted file mode 100644
index 2691e56..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeAssetManager.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layoutlib.bridge.Bridge;
-
-public class BridgeAssetManager extends AssetManager {
-
-    private AssetRepository mAssetRepository;
-
-    /**
-     * This initializes the static field {@link AssetManager#sSystem} which is used
-     * by methods who get a global asset manager using {@link AssetManager#getSystem()}.
-     * <p/>
-     * They will end up using our bridge asset manager.
-     * <p/>
-     * {@link Bridge} calls this method after setting up a new bridge.
-     */
-    public static AssetManager initSystem() {
-        if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
-            // Note that AssetManager() creates a system AssetManager and we override it
-            // with our BridgeAssetManager.
-            AssetManager.sSystem = new BridgeAssetManager();
-            AssetManager.sSystem.makeStringBlocks(null);
-        }
-        return AssetManager.sSystem;
-    }
-
-    /**
-     * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
-     * around that would prevent us from unloading the library.
-     */
-    public static void clearSystem() {
-        AssetManager.sSystem = null;
-    }
-
-    public void setAssetRepository(AssetRepository assetRepository) {
-        mAssetRepository = assetRepository;
-    }
-
-    public AssetRepository getAssetRepository() {
-        return mAssetRepository;
-    }
-
-    public BridgeAssetManager() {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
deleted file mode 100644
index b5996af..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.LayoutInflater_Delegate;
-import android.view.ViewGroup.LayoutParams;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Map;
-
-import static android.util.TypedValue.TYPE_ATTRIBUTE;
-import static android.util.TypedValue.TYPE_DIMENSION;
-import static android.util.TypedValue.TYPE_FLOAT;
-import static android.util.TypedValue.TYPE_INT_BOOLEAN;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
-import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
-import static android.util.TypedValue.TYPE_INT_DEC;
-import static android.util.TypedValue.TYPE_INT_HEX;
-import static android.util.TypedValue.TYPE_NULL;
-import static android.util.TypedValue.TYPE_REFERENCE;
-import static android.util.TypedValue.TYPE_STRING;
-import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
-import static com.android.SdkConstants.PREFIX_THEME_REF;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL;
-import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED;
-
-/**
- * Custom implementation of TypedArray to handle non compiled resources.
- */
-public final class BridgeTypedArray extends TypedArray {
-
-    private final Resources mBridgeResources;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private final ResourceValue[] mResourceData;
-    private final String[] mNames;
-    private final boolean[] mIsFramework;
-
-    // Contains ids that are @empty. We still store null in mResourceData for that index, since we
-    // want to save on the check against empty, each time a resource value is requested.
-    @Nullable
-    private int[] mEmptyIds;
-
-    public BridgeTypedArray(Resources resources, BridgeContext context, int len,
-            boolean platformFile) {
-        super(resources);
-        mBridgeResources = resources;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mResourceData = new ResourceValue[len];
-        mNames = new String[len];
-        mIsFramework = new boolean[len];
-    }
-
-    /**
-     * A bridge-specific method that sets a value in the type array
-     * @param index the index of the value in the TypedArray
-     * @param name the name of the attribute
-     * @param isFramework whether the attribute is in the android namespace.
-     * @param value the value of the attribute
-     */
-    public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) {
-        mResourceData[index] = value;
-        mNames[index] = name;
-        mIsFramework[index] = isFramework;
-    }
-
-    /**
-     * Seals the array after all calls to
-     * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done.
-     * <p/>This allows to compute the list of non default values, permitting
-     * {@link #getIndexCount()} to return the proper value.
-     */
-    public void sealArray() {
-        // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
-        // first count the array size
-        int count = 0;
-        ArrayList<Integer> emptyIds = null;
-        for (int i = 0; i < mResourceData.length; i++) {
-            ResourceValue data = mResourceData[i];
-            if (data != null) {
-                String dataValue = data.getValue();
-                if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) {
-                    mResourceData[i] = null;
-                } else if (REFERENCE_EMPTY.equals(dataValue)) {
-                    mResourceData[i] = null;
-                    if (emptyIds == null) {
-                        emptyIds = new ArrayList<Integer>(4);
-                    }
-                    emptyIds.add(i);
-                } else {
-                    count++;
-                }
-            }
-        }
-
-        if (emptyIds != null) {
-            mEmptyIds = new int[emptyIds.size()];
-            for (int i = 0; i < emptyIds.size(); i++) {
-                mEmptyIds[i] = emptyIds.get(i);
-            }
-        }
-
-        // allocate the table with an extra to store the size
-        mIndices = new int[count+1];
-        mIndices[0] = count;
-
-        // fill the array with the indices.
-        int index = 1;
-        for (int i = 0 ; i < mResourceData.length ; i++) {
-            if (mResourceData[i] != null) {
-                mIndices[index++] = i;
-            }
-        }
-    }
-
-    /**
-     * Set the theme to be used for inflating drawables.
-     */
-    public void setTheme(Theme theme) {
-        mTheme = theme;
-    }
-
-    /**
-     * Return the number of values in this array.
-     */
-    @Override
-    public int length() {
-        return mResourceData.length;
-    }
-
-    /**
-     * Return the Resources object this array was loaded from.
-     */
-    @Override
-    public Resources getResources() {
-        return mBridgeResources;
-    }
-
-    /**
-     * Retrieve the styled string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence holding string data.  May be styled.  Returns
-     *         null if the attribute is not defined.
-     */
-    @Override
-    public CharSequence getText(int index) {
-        // FIXME: handle styled strings!
-        return getString(index);
-    }
-
-    /**
-     * Retrieve the string value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return String holding string data.  Any styling information is
-     * removed.  Returns null if the attribute is not defined.
-     */
-    @Override
-    public String getString(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        // As unfortunate as it is, it's possible to use enums with all attribute formats,
-        // not just integers/enums. So, we need to search the enums always. In case
-        // enums are used, the returned value is an integer.
-        Integer v = resolveEnumAttribute(index);
-        return v == null ? mResourceData[index].getValue() : String.valueOf((int) v);
-    }
-
-    /**
-     * Retrieve the boolean value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute boolean value, or defValue if not defined.
-     */
-    @Override
-    public boolean getBoolean(int index, boolean defValue) {
-        String s = getString(index);
-        return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue);
-
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined.
-     *
-     * @return Attribute int value, or defValue if not defined.
-     */
-    @Override
-    public int getInt(int index, int defValue) {
-        String s = getString(index);
-        try {
-            return convertValueToInt(s, defValue);
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the float value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute float value, or defValue if not defined..
-     */
-    @Override
-    public float getFloat(int index, float defValue) {
-        String s = getString(index);
-        try {
-            if (s != null) {
-                    return Float.parseFloat(s);
-            }
-        } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.",
-                            s, mNames[index]),
-                    null);
-        }
-        return defValue;
-    }
-
-    /**
-     * Retrieve the color value for the attribute at <var>index</var>.  If
-     * the attribute references a color resource holding a complex
-     * {@link android.content.res.ColorStateList}, then the default color from
-     * the set is returned.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute color value, or defValue if not defined.
-     */
-    @Override
-    public int getColor(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        ColorStateList colorStateList = ResourceHelper.getColorStateList(
-                mResourceData[index], mContext);
-        if (colorStateList != null) {
-            return colorStateList.getDefaultColor();
-        }
-
-        return defValue;
-    }
-
-    @Override
-    public ColorStateList getColorStateList(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getColorStateList(mResourceData[index], mContext);
-    }
-
-    @Override
-    public ComplexColor getComplexColor(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        return ResourceHelper.getComplexColor(mResourceData[index], mContext);
-    }
-
-    /**
-     * Retrieve the integer value for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute integer value, or defValue if not defined.
-     */
-    @Override
-    public int getInteger(int index, int defValue) {
-        return getInt(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var>.  Unit
-     * conversions are based on the current {@link DisplayMetrics}
-     * associated with the resources this {@link TypedArray} object
-     * came from.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric, or defValue if not defined.
-     *
-     * @see #getDimensionPixelOffset
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public float getDimension(int index, float defValue) {
-        String s = getString(index);
-        if (s == null) {
-            return defValue;
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            return mValue.getDimension(mBridgeResources.getDisplayMetrics());
-        }
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as an offset in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for you.  An offset conversion involves simply
-     * truncating the base value to an integer.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelSize
-     */
-    @Override
-    public int getDimensionPixelOffset(int index, int defValue) {
-        return (int) getDimension(index, defValue);
-    }
-
-    /**
-     * Retrieve a dimensional unit attribute at <var>index</var> for use
-     * as a size in raw pixels.  This is the same as
-     * {@link #getDimension}, except the returned value is converted to
-     * integer pixels for use as a size.  A size conversion involves
-     * rounding the base value, and ensuring that a non-zero base value
-     * is at least one pixel in size.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels, or defValue if not defined.
-     *
-     * @see #getDimension
-     * @see #getDimensionPixelOffset
-     */
-    @Override
-    public int getDimensionPixelSize(int index, int defValue) {
-        try {
-            return getDimension(index, null);
-        } catch (RuntimeException e) {
-            String s = getString(index);
-
-            if (s != null) {
-                // looks like we were unable to resolve the dimension value
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                                s, mNames[index]), null);
-            }
-
-            return defValue;
-        }
-    }
-
-    /**
-     * Special version of {@link #getDimensionPixelSize} for retrieving
-     * {@link android.view.ViewGroup}'s layout_width and layout_height
-     * attributes.  This is only here for performance reasons; applications
-     * should use {@link #getDimensionPixelSize}.
-     *
-     * @param index Index of the attribute to retrieve.
-     * @param name Textual name of attribute for error reporting.
-     *
-     * @return Attribute dimension value multiplied by the appropriate
-     * metric and truncated to integer pixels.
-     */
-    @Override
-    public int getLayoutDimension(int index, String name) {
-        try {
-            // this will throw an exception if not found.
-            return getDimension(index, name);
-        } catch (RuntimeException e) {
-
-            if (LayoutInflater_Delegate.sIsInInclude) {
-                throw new RuntimeException("Layout Dimension '" + name + "' not found.");
-            }
-
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    "You must supply a " + name + " attribute.", null);
-
-            return 0;
-        }
-    }
-
-    @Override
-    public int getLayoutDimension(int index, int defValue) {
-        return getDimensionPixelSize(index, defValue);
-    }
-
-    /** @param name attribute name, used for error reporting. */
-    private int getDimension(int index, @Nullable String name) {
-        String s = getString(index);
-        if (s == null) {
-            if (name != null) {
-                throw new RuntimeException("Attribute '" + name + "' not found");
-            }
-            throw new RuntimeException();
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
-
-            final int res = (int)(f+0.5f);
-            if (res != 0) return res;
-            if (f == 0) return 0;
-            if (f > 0) return 1;
-        }
-
-        throw new RuntimeException();
-    }
-
-    /**
-     * Retrieve a fractional unit attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param base The base value of this fraction.  In other words, a
-     *             standard fraction is multiplied by this value.
-     * @param pbase The parent base value of this fraction.  In other
-     *             words, a parent fraction (nn%p) is multiplied by this
-     *             value.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute fractional value multiplied by the appropriate
-     * base value, or defValue if not defined.
-     */
-    @Override
-    public float getFraction(int index, int base, int pbase, float defValue) {
-        String value = getString(index);
-        if (value == null) {
-            return defValue;
-        }
-
-        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) {
-            return mValue.getFraction(base, pbase);
-        }
-
-        // looks like we were unable to resolve the fraction value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                String.format(
-                        "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
-                        value, mNames[index]), null);
-
-        return defValue;
-    }
-
-    /**
-     * Retrieve the resource identifier for the attribute at
-     * <var>index</var>.  Note that attribute resource as resolved when
-     * the overall {@link TypedArray} object is retrieved.  As a
-     * result, this function will return the resource identifier of the
-     * final resource value that was found, <em>not</em> necessarily the
-     * original resource that was specified by the attribute.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param defValue Value to return if the attribute is not defined or
-     *                 not a resource.
-     *
-     * @return Attribute resource identifier, or defValue if not defined.
-     */
-    @Override
-    public int getResourceId(int index, int defValue) {
-        if (index < 0 || index >= mResourceData.length) {
-            return defValue;
-        }
-
-        // get the Resource for this index
-        ResourceValue resValue = mResourceData[index];
-
-        // no data, return the default value.
-        if (resValue == null) {
-            return defValue;
-        }
-
-        // check if this is a style resource
-        if (resValue instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
-        }
-
-        // if the attribute was a reference to a resource, and not a declaration of an id (@+id),
-        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
-        // valid getType() and getName() returning a resource name.
-        // (and getValue() returning null!). We need to handle this!
-        if (resValue.getResourceType() != null) {
-            // if this is a framework id
-            if (mPlatformFile || resValue.isFramework()) {
-                // look for idName in the android R classes
-                return mContext.getFrameworkResourceValue(
-                        resValue.getResourceType(), resValue.getName(), defValue);
-            }
-
-            // look for idName in the project R class.
-            return mContext.getProjectResourceValue(
-                    resValue.getResourceType(), resValue.getName(), defValue);
-        }
-
-        // else, try to get the value, and resolve it somehow.
-        String value = resValue.getValue();
-        if (value == null) {
-            return defValue;
-        }
-        value = value.trim();
-
-        // if the value is just an integer, return it.
-        try {
-            int i = Integer.parseInt(value);
-            if (Integer.toString(i).equals(value)) {
-                return i;
-            }
-        } catch (NumberFormatException e) {
-            // pass
-        }
-
-        if (value.startsWith("#")) {
-            // this looks like a color, do not try to parse it
-            return defValue;
-        }
-
-        // Handle the @id/<name>, @+id/<name> and @android:id/<name>
-        // We need to return the exact value that was compiled (from the various R classes),
-        // as these values can be reused internally with calls to findViewById().
-        // There's a trick with platform layouts that not use "android:" but their IDs are in
-        // fact in the android.R and com.android.internal.R classes.
-        // The field mPlatformFile will indicate that all IDs are to be looked up in the android R
-        // classes exclusively.
-
-        // if this is a reference to an id, find it.
-        if (value.startsWith("@id/") || value.startsWith("@+") ||
-                value.startsWith("@android:id/")) {
-
-            int pos = value.indexOf('/');
-            String idName = value.substring(pos + 1);
-            boolean create = value.startsWith("@+");
-            boolean isFrameworkId =
-                    mPlatformFile || value.startsWith("@android") || value.startsWith("@+android");
-
-            // Look for the idName in project or android R class depending on isPlatform.
-            if (create) {
-                Integer idValue;
-                if (isFrameworkId) {
-                    idValue = Bridge.getResourceId(ResourceType.ID, idName);
-                } else {
-                    idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName);
-                }
-                return idValue == null ? defValue : idValue;
-            }
-            // This calls the same method as in if(create), but doesn't create a dynamic id, if
-            // one is not found.
-            if (isFrameworkId) {
-                return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
-            } else {
-                return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
-            }
-        }
-        else if (value.startsWith("@aapt:_aapt")) {
-            return mContext.getLayoutlibCallback().getResourceId(ResourceType.AAPT, value);
-        }
-
-        // not a direct id valid reference. First check if it's an enum (this is a corner case
-        // for attributes that have a reference|enum type), then fallback to resolve
-        // as an ID without prefix.
-        Integer enumValue = resolveEnumAttribute(index);
-        if (enumValue != null) {
-            return enumValue;
-        }
-
-        // Ok, not an enum, resolve as an ID
-        Integer idValue;
-
-        if (resValue.isFramework()) {
-            idValue = Bridge.getResourceId(resValue.getResourceType(),
-                    resValue.getName());
-        } else {
-            idValue = mContext.getLayoutlibCallback().getResourceId(
-                    resValue.getResourceType(), resValue.getName());
-        }
-
-        if (idValue != null) {
-            return idValue;
-        }
-
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
-                String.format(
-                    "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
-                    resValue);
-
-        return defValue;
-    }
-
-    @Override
-    public int getThemeAttributeId(int index, int defValue) {
-        // TODO: Get the right Theme Attribute ID to enable caching of the drawables.
-        return defValue;
-    }
-
-    /**
-     * Retrieve the Drawable for the attribute at <var>index</var>.  This
-     * gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getDrawable Resources.getDrawable} of the owning
-     * Resources object to retrieve its Drawable.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Drawable for the attribute, or null if not defined.
-     */
-    @Override
-    public Drawable getDrawable(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getDrawable(value, mContext, mTheme);
-    }
-
-    /**
-     * Version of {@link #getDrawable(int)} that accepts an override density.
-     * @hide
-     */
-    @Override
-    public Drawable getDrawableForDensity(int index, int density) {
-        return getDrawable(index);
-    }
-
-    /**
-     * Retrieve the Typeface for the attribute at <var>index</var>.
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Typeface for the attribute, or null if not defined.
-     */
-    @Override
-    public Typeface getFont(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-
-        ResourceValue value = mResourceData[index];
-        return ResourceHelper.getFont(value, mContext, mTheme);
-    }
-
-    /**
-     * Retrieve the CharSequence[] for the attribute at <var>index</var>.
-     * This gets the resource ID of the selected attribute, and uses
-     * {@link Resources#getTextArray Resources.getTextArray} of the owning
-     * Resources object to retrieve its String[].
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return CharSequence[] for the attribute, or null if not defined.
-     */
-    @Override
-    public CharSequence[] getTextArray(int index) {
-        if (!hasValue(index)) {
-            return null;
-        }
-        ResourceValue resVal = mResourceData[index];
-        if (resVal instanceof ArrayResourceValue) {
-            ArrayResourceValue array = (ArrayResourceValue) resVal;
-            int count = array.getElementCount();
-            return count >= 0 ? Resources_Delegate.fillValues(mBridgeResources, array, new CharSequence[count]) :
-                    null;
-        }
-        int id = getResourceId(index, 0);
-        String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : "";
-        assert false :
-                String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(),
-                        mNames[index], resIdMessage);
-
-        return new CharSequence[0];
-    }
-
-    @Override
-    public int[] extractThemeAttrs() {
-        // The drawables are always inflated with a Theme and we don't care about caching. So,
-        // just return.
-        return null;
-    }
-
-    @Override
-    public int getChangingConfigurations() {
-        // We don't care about caching. Any change in configuration is a fresh render. So,
-        // just return.
-        return 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     * @param outValue TypedValue object in which to place the attribute's
-     *                 data.
-     *
-     * @return Returns true if the value was retrieved, else false.
-     */
-    @Override
-    public boolean getValue(int index, TypedValue outValue) {
-        // TODO: more switch cases for other types.
-        outValue.type = getType(index);
-        switch (outValue.type) {
-            case TYPE_NULL:
-                return false;
-            case TYPE_STRING:
-                outValue.string = getString(index);
-                return true;
-            default:
-                // For back-compatibility, parse as float.
-                String s = getString(index);
-                return s != null &&
-                        ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
-        }
-    }
-
-    @Override
-    @SuppressWarnings("ResultOfMethodCallIgnored")
-    public int getType(int index) {
-        String value = getString(index);
-        if (value == null) {
-            return TYPE_NULL;
-        }
-        if (value.startsWith(PREFIX_RESOURCE_REF)) {
-            return TYPE_REFERENCE;
-        }
-        if (value.startsWith(PREFIX_THEME_REF)) {
-            return TYPE_ATTRIBUTE;
-        }
-        try {
-            // Don't care about the value. Only called to check if an exception is thrown.
-            convertValueToInt(value, 0);
-            if (value.startsWith("0x") || value.startsWith("0X")) {
-                return TYPE_INT_HEX;
-            }
-            // is it a color?
-            if (value.startsWith("#")) {
-                int length = value.length() - 1;
-                if (length == 3) {  // rgb
-                    return TYPE_INT_COLOR_RGB4;
-                }
-                if (length == 4) {  // argb
-                    return TYPE_INT_COLOR_ARGB4;
-                }
-                if (length == 6) {  // rrggbb
-                    return TYPE_INT_COLOR_RGB8;
-                }
-                if (length == 8) {  // aarrggbb
-                    return TYPE_INT_COLOR_ARGB8;
-                }
-            }
-            if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
-                return TYPE_INT_BOOLEAN;
-            }
-            return TYPE_INT_DEC;
-        } catch (NumberFormatException ignored) {
-            try {
-                Float.parseFloat(value);
-                return TYPE_FLOAT;
-            } catch (NumberFormatException ignore) {
-            }
-            // Might be a dimension.
-            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
-                return TYPE_DIMENSION;
-            }
-        }
-        // TODO: handle fractions.
-        return TYPE_STRING;
-    }
-
-    /**
-     * Determines whether there is an attribute at <var>index</var>.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return True if the attribute has a value, false otherwise.
-     */
-    @Override
-    public boolean hasValue(int index) {
-        return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
-    }
-
-    @Override
-    public boolean hasValueOrEmpty(int index) {
-        return hasValue(index) || index >= 0 && index < mResourceData.length &&
-                mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0;
-    }
-
-    /**
-     * Retrieve the raw TypedValue for the attribute at <var>index</var>
-     * and return a temporary object holding its data.  This object is only
-     * valid until the next call on to {@link TypedArray}.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Returns a TypedValue object if the attribute is defined,
-     *         containing its data; otherwise returns null.  (You will not
-     *         receive a TypedValue whose type is TYPE_NULL.)
-     */
-    @Override
-    public TypedValue peekValue(int index) {
-        if (index < 0 || index >= mResourceData.length) {
-            return null;
-        }
-
-        if (getValue(index, mValue)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a message about the parser state suitable for printing error messages.
-     */
-    @Override
-    public String getPositionDescription() {
-        return "<internal -- stub if needed>";
-    }
-
-    /**
-     * Give back a previously retrieved TypedArray, for later re-use.
-     */
-    @Override
-    public void recycle() {
-        // pass
-    }
-
-    @Override
-    public String toString() {
-        return Arrays.toString(mResourceData);
-    }
-
-    /**
-     * Searches for the string in the attributes (flag or enums) and returns the integer.
-     * If found, it will return an integer matching the value.
-     *
-     * @param index Index of attribute to retrieve.
-     *
-     * @return Attribute int value, or null if not defined.
-     */
-    private Integer resolveEnumAttribute(int index) {
-        // Get the map of attribute-constant -> IntegerValue
-        Map<String, Integer> map = null;
-        if (mIsFramework[index]) {
-            map = Bridge.getEnumValues(mNames[index]);
-        } else {
-            // get the styleable matching the resolved name
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
-            if (attr instanceof AttrResourceValue) {
-                map = ((AttrResourceValue) attr).getAttributeValues();
-            }
-        }
-
-        if (map != null) {
-            // accumulator to store the value of the 1+ constants.
-            int result = 0;
-            boolean found = false;
-
-            // split the value in case this is a mix of several flags.
-            String[] keywords = mResourceData[index].getValue().split("\\|");
-            for (String keyword : keywords) {
-                Integer i = map.get(keyword.trim());
-                if (i != null) {
-                    result |= i;
-                    found = true;
-                }
-                // TODO: We should act smartly and log a warning for incorrect keywords. However,
-                // this method is currently called even if the resourceValue is not an enum.
-            }
-            if (found) {
-                return result;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account
-     * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle
-     * "XXXXXXXX" > 80000000.
-     */
-    private static int convertValueToInt(@Nullable String charSeq, int defValue) {
-        if (null == charSeq || charSeq.isEmpty())
-            return defValue;
-
-        int sign = 1;
-        int index = 0;
-        int len = charSeq.length();
-        int base = 10;
-
-        if ('-' == charSeq.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == charSeq.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = charSeq.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                // Leave the base as 10. aapt removes the preceding zero, and thus when framework
-                // sees the value, it only gets the decimal value.
-            }
-        } else if ('#' == charSeq.charAt(index)) {
-            return ResourceHelper.getColor(charSeq) * sign;
-        } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) {
-            return -1;
-        } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) {
-            return 0;
-        }
-
-        // Use Long, since we want to handle hex ints > 80000000.
-        return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
-    }
-
-    static TypedArray obtain(Resources res, int len) {
-        return new BridgeTypedArray(res, null, len, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java b/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
deleted file mode 100644
index 09c0260..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/ComplexColor_Accessor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.Theme;
-import android.util.AttributeSet;
-
-import java.io.IOException;
-
-/**
- * Class that provides access to the {@link GradientColor#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} and {@link ColorStateList#createFromXmlInner(Resources,
- * XmlPullParser, AttributeSet, Theme)} methods
- */
-public class ComplexColor_Accessor {
-    public static GradientColor createGradientColorFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return GradientColor.createFromXmlInner(r, parser, attrs, theme);
-    }
-
-    public static ColorStateList createColorStateListFromXmlInner(@NonNull Resources r,
-            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
-            throws IOException, XmlPullParserException {
-        return ColorStateList.createFromXmlInner(r, parser, attrs, theme);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
deleted file mode 100644
index c20ee12..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ArrayResourceValue;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.PluralsResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import com.android.ninepatch.NinePatch;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.icu.text.PluralRules;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.LruCache;
-import android.util.TypedValue;
-import android.view.DisplayAdjustments;
-import android.view.ViewGroup.LayoutParams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Iterator;
-
-@SuppressWarnings("deprecation")
-public class Resources_Delegate {
-
-    private static boolean[] mPlatformResourceFlag = new boolean[1];
-    // TODO: This cache is cleared every time a render session is disposed. Look into making this
-    // more long lived.
-    private static LruCache<String, Drawable.ConstantState> sDrawableCache = new LruCache<>(50);
-
-    public static Resources initSystem(BridgeContext context,
-            AssetManager assets,
-            DisplayMetrics metrics,
-            Configuration config,
-            LayoutlibCallback layoutlibCallback) {
-        Resources resources = new Resources(Resources_Delegate.class.getClassLoader());
-        resources.setImpl(new ResourcesImpl(assets, metrics, config, new DisplayAdjustments()));
-        resources.mContext = context;
-        resources.mLayoutlibCallback = layoutlibCallback;
-        return Resources.mSystem = resources;
-    }
-
-    /**
-     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects around that
-     * would prevent us from unloading the library.
-     */
-    public static void disposeSystem() {
-        sDrawableCache.evictAll();
-        Resources.mSystem.mContext = null;
-        Resources.mSystem.mLayoutlibCallback = null;
-        Resources.mSystem = null;
-    }
-
-    public static BridgeTypedArray newTypeArray(Resources resources, int numEntries,
-            boolean platformFile) {
-        return new BridgeTypedArray(resources, resources.mContext, numEntries, platformFile);
-    }
-
-    private static Pair<ResourceType, String> getResourceInfo(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        // Set the layoutlib callback and context for resources
-        if (resources != Resources.mSystem && resources.mLayoutlibCallback == null) {
-            resources.mLayoutlibCallback = Resources.mSystem.mLayoutlibCallback;
-            resources.mContext = Resources.mSystem.mContext;
-        }
-
-        if (resourceInfo != null) {
-            platformResFlag_out[0] = true;
-            return resourceInfo;
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (resources.mLayoutlibCallback != null) {
-            resourceInfo = resources.mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                platformResFlag_out[0] = false;
-                return resourceInfo;
-            }
-        }
-        return null;
-    }
-
-    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
-            boolean[] platformResFlag_out) {
-        Pair<ResourceType, String> resourceInfo =
-                getResourceInfo(resources, id, platformResFlag_out);
-
-        if (resourceInfo != null) {
-            String attributeName = resourceInfo.getSecond();
-            RenderResources renderResources = resources.mContext.getRenderResources();
-            ResourceValue value = platformResFlag_out[0] ?
-                    renderResources.getFrameworkResource(resourceInfo.getFirst(), attributeName) :
-                    renderResources.getProjectResource(resourceInfo.getFirst(), attributeName);
-
-            if (value == null) {
-                // Unable to resolve the attribute, just leave the unresolved value
-                value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName,
-                        platformResFlag_out[0]);
-            }
-            return Pair.of(attributeName, value);
-        }
-
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id) {
-        return getDrawable(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static Drawable getDrawable(Resources resources, int id, Theme theme) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            String key = value.getSecond().getValue();
-
-            Drawable.ConstantState constantState = key != null ? sDrawableCache.get(key) : null;
-            Drawable drawable;
-            if (constantState != null) {
-                drawable = constantState.newDrawable(resources, theme);
-            } else {
-                drawable =
-                        ResourceHelper.getDrawable(value.getSecond(), resources.mContext, theme);
-
-                if (key != null) {
-                    sDrawableCache.put(key, drawable.getConstantState());
-                }
-            }
-
-            return drawable;
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id) {
-        return getColor(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static int getColor(Resources resources, int id, Theme theme) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resourceValue = value.getSecond();
-            try {
-                return ResourceHelper.getColor(resourceValue.getValue());
-            } catch (NumberFormatException e) {
-                // Check if the value passed is a file. If it is, mostly likely, user is referencing
-                // a color state list from a place where they should reference only a pure color.
-                String message;
-                if (new File(resourceValue.getValue()).isFile()) {
-                    String resource = (resourceValue.isFramework() ? "@android:" : "@") + "color/"
-                            + resourceValue.getName();
-                    message = "Hexadecimal color expected, found Color State List for " + resource;
-                } else {
-                    message = e.getMessage();
-                }
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null);
-                return 0;
-            }
-        }
-
-        // Suppress possible NPE. getColorStateList will never return null, it will instead
-        // throw an exception, but intelliJ can't figure that out
-        //noinspection ConstantConditions
-        return getColorStateList(resources, id, theme).getDefaultColor();
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id) throws NotFoundException {
-        return getColorStateList(resources, id, null);
-    }
-
-    @LayoutlibDelegate
-    static ColorStateList getColorStateList(Resources resources, int id, Theme theme)
-            throws NotFoundException {
-        Pair<String, ResourceValue> resValue =
-                getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (resValue != null) {
-            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
-                    resources.mContext);
-            if (stateList != null) {
-                return stateList.obtainForTheme(theme);
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id, CharSequence def) {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getText(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return v;
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static CharSequence[] getTextArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new CharSequence[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new CharSequence[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new CharSequence[arv.getElementCount()]);
-    }
-
-    @LayoutlibDelegate
-    static String[] getStringArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue resValue = getArrayResourceValue(resources, id);
-        if (resValue == null) {
-            // Error already logged by getArrayResourceValue.
-            return new String[0];
-        } else if (!(resValue instanceof ArrayResourceValue)) {
-            return new String[]{
-                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
-        }
-        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
-        return fillValues(resources, arv, new String[arv.getElementCount()]);
-    }
-
-    /**
-     * Resolve each element in resValue and copy them to {@code values}. The values copied are
-     * always Strings. The ideal signature for the method should be &lt;T super String&gt;, but java
-     * generics don't support it.
-     */
-    static <T extends CharSequence> T[] fillValues(Resources resources, ArrayResourceValue resValue,
-            T[] values) {
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            @SuppressWarnings("unchecked")
-            T s = (T) resolveReference(resources, iterator.next(), resValue.isFramework());
-            values[i] = s;
-        }
-        return values;
-    }
-
-    @LayoutlibDelegate
-    static int[] getIntArray(Resources resources, int id) throws NotFoundException {
-        ResourceValue rv = getArrayResourceValue(resources, id);
-        if (rv == null) {
-            // Error already logged by getArrayResourceValue.
-            return new int[0];
-        } else if (!(rv instanceof ArrayResourceValue)) {
-            // This is an older IDE that can only give us the first element of the array.
-            String firstValue = resolveReference(resources, rv.getValue(), rv.isFramework());
-            try {
-                return new int[]{getInt(firstValue)};
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " +
-                                firstValue, null);
-                return new int[1];
-            }
-        }
-        ArrayResourceValue resValue = ((ArrayResourceValue) rv);
-        int[] values = new int[resValue.getElementCount()];
-        int i = 0;
-        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
-            String element = resolveReference(resources, iterator.next(), resValue.isFramework());
-            try {
-                values[i] = getInt(element);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Integer resource array contains non-integer value: " + element, null);
-            }
-        }
-        return values;
-    }
-
-    /**
-     * Try to find the ArrayResourceValue for the given id.
-     * <p/>
-     * If the ResourceValue found is not of type {@link ResourceType#ARRAY}, the method logs an
-     * error and return null. However, if the ResourceValue found has type {@code
-     * ResourceType.ARRAY}, but the value is not an instance of {@link ArrayResourceValue}, the
-     * method returns the ResourceValue. This happens on older versions of the IDE, which did not
-     * parse the array resources properly.
-     * <p/>
-     *
-     * @throws NotFoundException if no resource if found
-     */
-    @Nullable
-    private static ResourceValue getArrayResourceValue(Resources resources, int id)
-            throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue resValue = v.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                final ResourceType type = resValue.getResourceType();
-                if (type != ResourceType.ARRAY) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                            String.format(
-                                    "Resource with id 0x%1$X is not an array resource, but %2$s",
-                                    id, type == null ? "null" : type.getDisplayName()),
-                            null);
-                    return null;
-                }
-                if (!(resValue instanceof ArrayResourceValue)) {
-                    Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
-                            "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.",
-                            null);
-                }
-                return resValue;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @NonNull
-    private static String resolveReference(Resources resources, @NonNull String ref,
-            boolean forceFrameworkOnly) {
-        if (ref.startsWith(SdkConstants.PREFIX_RESOURCE_REF) || ref.startsWith
-                (SdkConstants.PREFIX_THEME_REF)) {
-            ResourceValue rv =
-                    resources.mContext.getRenderResources().findResValue(ref, forceFrameworkOnly);
-            rv = resources.mContext.getRenderResources().resolveResValue(rv);
-            if (rv != null) {
-                return rv.getValue();
-            }
-        }
-        // Not a reference.
-        return ref;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getLayout(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser = null;
-
-            try {
-                // check if the current parser can provide us with a custom parser.
-                if (!mPlatformResourceFlag[0]) {
-                    parser = resources.mLayoutlibCallback.getParser(value);
-                }
-
-                // create a new one manually if needed.
-                if (parser == null) {
-                    File xml = new File(value.getValue());
-                    if (xml.isFile()) {
-                        // we need to create a pull parser around the layout XML file, and then
-                        // give that to our XmlBlockParser
-                        parser = ParserFactory.create(xml, true);
-                    }
-                }
-
-                if (parser != null) {
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getAnimation(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (v != null) {
-            ResourceValue value = v.getSecond();
-            XmlPullParser parser;
-
-            try {
-                File xml = new File(value.getValue());
-                if (xml.isFile()) {
-                    // we need to create a pull parser around the layout XML file, and then
-                    // give that to our XmlBlockParser
-                    parser = ParserFactory.create(xml);
-
-                    return new BridgeXmlBlockParser(parser, resources.mContext,
-                            mPlatformResourceFlag[0]);
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
-                // we'll return null below.
-            } catch (FileNotFoundException e) {
-                // this shouldn't happen since we check above.
-            }
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, AttributeSet set, int[] attrs) {
-        return resources.mContext.obtainStyledAttributes(set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainAttributes(Resources resources, Resources.Theme theme, AttributeSet
-            set, int[] attrs) {
-        return Resources.obtainAttributes_Original(resources, theme, set, attrs);
-    }
-
-    @LayoutlibDelegate
-    static TypedArray obtainTypedArray(Resources resources, int id) throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static float getDimension(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
-                            v.equals(BridgeConstants.FILL_PARENT)) {
-                        return LayoutParams.MATCH_PARENT;
-                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
-                        return LayoutParams.WRAP_CONTENT;
-                    }
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return tmpValue.getDimension(resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelOffset(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelOffset(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getDimensionPixelSize(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    TypedValue tmpValue = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute(
-                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
-                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
-                        return TypedValue.complexToDimensionPixelSize(tmpValue.data,
-                                resources.getDisplayMetrics());
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static int getInteger(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            assert resValue != null;
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    try {
-                        return getInt(v);
-                    } catch (NumberFormatException e) {
-                        // return exception below
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    static boolean getBoolean(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resValue = value.getSecond();
-
-            if (resValue != null) {
-                String v = resValue.getValue();
-                if (v != null) {
-                    return Boolean.parseBoolean(v);
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return false;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceEntryName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-
-    }
-
-    @LayoutlibDelegate
-    static String getResourceName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        String packageName;
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                packageName = SdkConstants.ANDROID_NS_NAME;
-            } else {
-                packageName = resources.mContext.getPackageName();
-                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
-            }
-            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
-                    resourceInfo.getSecond();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourcePackageName(Resources resources, int resid) throws NotFoundException {
-        boolean[] platformOut = new boolean[1];
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
-        if (resourceInfo != null) {
-            if (platformOut[0]) {
-                return SdkConstants.ANDROID_NS_NAME;
-            }
-            String packageName = resources.mContext.getPackageName();
-            return packageName == null ? SdkConstants.APP_PREFIX : packageName;
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getResourceTypeName(Resources resources, int resid) throws NotFoundException {
-        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
-        if (resourceInfo != null) {
-            return resourceInfo.getFirst().getName();
-        }
-        throwException(resid, null);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id, Object... formatArgs)
-            throws NotFoundException {
-        String s = getString(resources, id);
-        if (s != null) {
-            return String.format(s, formatArgs);
-
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getString(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null && value.getSecond().getValue() != null) {
-            return value.getSecond().getValue();
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            if (value.getSecond() instanceof PluralsResourceValue) {
-                PluralsResourceValue pluralsResourceValue = (PluralsResourceValue) value.getSecond();
-                PluralRules pluralRules = PluralRules.forLocale(resources.getConfiguration().getLocales()
-                        .get(0));
-                String strValue = pluralsResourceValue.getValue(pluralRules.select(quantity));
-                if (strValue == null) {
-                    strValue = pluralsResourceValue.getValue(PluralRules.KEYWORD_OTHER);
-                }
-
-                return strValue;
-            }
-            else {
-                return value.getSecond().getValue();
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static String getQuantityString(Resources resources, int id, int quantity, Object... formatArgs)
-            throws NotFoundException {
-        String raw = getQuantityString(resources, id, quantity);
-        return String.format(resources.getConfiguration().getLocales().get(0), raw, formatArgs);
-    }
-
-    @LayoutlibDelegate
-    static CharSequence getQuantityText(Resources resources, int id, int quantity) throws
-            NotFoundException {
-        return getQuantityString(resources, id, quantity);
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, int id) throws
-            NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-        if (value != null) {
-            return ResourceHelper.getFont(value.getSecond(), resources.mContext, null);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static Typeface getFont(Resources resources, TypedValue outValue, int id) throws
-            NotFoundException {
-        Resources_Delegate.getValue(resources, id, outValue, true);
-        if (outValue.string != null) {
-            return ResourceHelper.getFont(outValue.string.toString(), resources.mContext, null,
-                    mPlatformResourceFlag[0]);
-        }
-
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, int id, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            ResourceValue resVal = value.getSecond();
-            String v = resVal.getValue();
-
-            if (v != null) {
-                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
-                        false /*requireUnit*/)) {
-                    return;
-                }
-                if (resVal instanceof DensityBasedResourceValue) {
-                    outValue.density =
-                            ((DensityBasedResourceValue) resVal).getResourceDensity().getDpiValue();
-                }
-
-                // else it's a string
-                outValue.type = TypedValue.TYPE_STRING;
-                outValue.string = v;
-                return;
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-    }
-
-    @LayoutlibDelegate
-    static void getValue(Resources resources, String name, TypedValue outValue, boolean resolveRefs)
-            throws NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser getXml(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String v = value.getSecond().getValue();
-
-            if (v != null) {
-                // check this is a file
-                File f = new File(v);
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f);
-
-                        return new BridgeXmlBlockParser(parser, resources.mContext,
-                                mPlatformResourceFlag[0]);
-                    } catch (XmlPullParserException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, int id,
-            String type) throws NotFoundException {
-        return resources.loadXmlResourceParser_Original(id, type);
-    }
-
-    @LayoutlibDelegate
-    static XmlResourceParser loadXmlResourceParser(Resources resources, String file, int id,
-            int assetCookie, String type) throws NotFoundException {
-        // even though we know the XML file to load directly, we still need to resolve the
-        // id so that we can know if it's a platform or project resource.
-        // (mPlatformResouceFlag will get the result and will be used later).
-        getResourceValue(resources, id, mPlatformResourceFlag);
-
-        File f = new File(file);
-        try {
-            XmlPullParser parser = ParserFactory.create(f);
-
-            return new BridgeXmlBlockParser(parser, resources.mContext, mPlatformResourceFlag[0]);
-        } catch (XmlPullParserException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        } catch (FileNotFoundException e) {
-            NotFoundException newE = new NotFoundException();
-            newE.initCause(e);
-            throw newE;
-        }
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id) throws NotFoundException {
-        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
-
-        if (value != null) {
-            String path = value.getSecond().getValue();
-
-            if (path != null) {
-                // check this is a file
-                File f = new File(path);
-                if (f.isFile()) {
-                    try {
-                        // if it's a nine-patch return a custom input stream so that
-                        // other methods (mainly bitmap factory) can detect it's a 9-patch
-                        // and actually load it as a 9-patch instead of a normal bitmap
-                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                            return new NinePatchInputStream(f);
-                        }
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {
-                        NotFoundException newE = new NotFoundException();
-                        newE.initCause(e);
-                        throw newE;
-                    }
-                }
-            }
-        }
-
-        // id was not found or not resolved. Throw a NotFoundException.
-        throwException(resources, id);
-
-        // this is not used since the method above always throws
-        return null;
-    }
-
-    @LayoutlibDelegate
-    static InputStream openRawResource(Resources resources, int id, TypedValue value) throws
-            NotFoundException {
-        getValue(resources, id, value, true);
-
-        String path = value.string.toString();
-
-        File f = new File(path);
-        if (f.isFile()) {
-            try {
-                // if it's a nine-patch return a custom input stream so that
-                // other methods (mainly bitmap factory) can detect it's a 9-patch
-                // and actually load it as a 9-patch instead of a normal bitmap
-                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
-                    return new NinePatchInputStream(f);
-                }
-                return new FileInputStream(f);
-            } catch (FileNotFoundException e) {
-                NotFoundException exception = new NotFoundException();
-                exception.initCause(e);
-                throw exception;
-            }
-        }
-
-        throw new NotFoundException();
-    }
-
-    @LayoutlibDelegate
-    static AssetFileDescriptor openRawResourceFd(Resources resources, int id) throws
-            NotFoundException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource
-     * type.
-     *
-     * @param id the id of the resource
-     *
-     * @throws NotFoundException
-     */
-    private static void throwException(Resources resources, int id) throws NotFoundException {
-        throwException(id, getResourceInfo(resources, id, new boolean[1]));
-    }
-
-    private static void throwException(int id, @Nullable Pair<ResourceType, String> resourceInfo) {
-        String message;
-        if (resourceInfo != null) {
-            message = String.format(
-                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
-                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
-        } else {
-            message = String.format("Could not resolve resource value: 0x%1$X.", id);
-        }
-
-        throw new NotFoundException(message);
-    }
-
-    private static int getInt(String v) throws NumberFormatException {
-        int radix = 10;
-        if (v.startsWith("0x")) {
-            v = v.substring(2);
-            radix = 16;
-        } else if (v.startsWith("0")) {
-            radix = 8;
-        }
-        return Integer.parseInt(v, radix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
deleted file mode 100644
index f1e8fc21..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources.ThemeKey;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Resources.Theme}
- *
- * Through the layoutlib_create tool, the original  methods of Theme have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Resources_Theme_Delegate {
-
-    // ---- delegate manager ----
-
-    private static final DelegateManager<Resources_Theme_Delegate> sManager =
-            new DelegateManager<Resources_Theme_Delegate>(Resources_Theme_Delegate.class);
-
-    public static DelegateManager<Resources_Theme_Delegate> getDelegateManager() {
-        return sManager;
-    }
-
-    // ---- delegate methods. ----
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int[] attrs) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            int resid, int[] attrs)
-            throws NotFoundException {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid,
-                attrs);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtainStyledAttributes(
-            Resources thisResources, Theme thisTheme,
-            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
-        boolean changed = setupResources(thisTheme);
-        BridgeTypedArray ta = RenderSessionImpl.getCurrentContext().obtainStyledAttributes(set,
-                attrs, defStyleAttr, defStyleRes);
-        ta.setTheme(thisTheme);
-        restoreResources(changed);
-        return ta;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean resolveAttribute(
-            Resources thisResources, Theme thisTheme,
-            int resid, TypedValue outValue,
-            boolean resolveRefs) {
-        boolean changed = setupResources(thisTheme);
-        boolean found =  RenderSessionImpl.getCurrentContext().resolveThemeAttribute(resid,
-                outValue, resolveRefs);
-        restoreResources(changed);
-        return found;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray resolveAttributes(Resources thisResources, Theme thisTheme,
-            int[] values, int[] attrs) {
-        // FIXME
-        return null;
-    }
-
-    // ---- private helper methods ----
-
-    private static boolean setupResources(Theme thisTheme) {
-        // Key is a space-separated list of theme ids applied that have been merged into the
-        // BridgeContext's theme to make thisTheme.
-        final ThemeKey key = thisTheme.getKey();
-        final int[] resId = key.mResId;
-        final boolean[] force = key.mForce;
-
-        boolean changed = false;
-        for (int i = 0, N = key.mCount; i < N; i++) {
-            StyleResourceValue style = resolveStyle(resId[i]);
-            if (style != null) {
-                RenderSessionImpl.getCurrentContext().getRenderResources().applyStyle(
-                        style, force[i]);
-                changed = true;
-            }
-
-        }
-        return changed;
-    }
-
-    private static void restoreResources(boolean changed) {
-        if (changed) {
-            RenderSessionImpl.getCurrentContext().getRenderResources().clearStyles();
-        }
-    }
-
-    @Nullable
-    private static StyleResourceValue resolveStyle(int nativeResid) {
-        if (nativeResid == 0) {
-            return null;
-        }
-        BridgeContext context = RenderSessionImpl.getCurrentContext();
-        ResourceReference theme = context.resolveId(nativeResid);
-        if (theme.isFramework()) {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getFrameworkResource(ResourceType.STYLE, theme.getName());
-        } else {
-            return (StyleResourceValue) context.getRenderResources()
-                    .getProjectResource(ResourceType.STYLE, theme.getName());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
deleted file mode 100644
index faa8852..0000000
--- a/tools/layoutlib/bridge/src/android/content/res/TypedArray_Delegate.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.TypedValue;
-
-public class TypedArray_Delegate {
-
-    @LayoutlibDelegate
-    public static boolean getValueAt(TypedArray theTypedArray, int index, TypedValue outValue) {
-        // pass
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static TypedArray obtain(Resources res, int len) {
-        return BridgeTypedArray.obtain(res, len);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
deleted file mode 100644
index cc71053..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BaseCanvas_Delegate.java
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.layoutlib.bridge.impl.PorterDuffUtility;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.text.TextUtils;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-
-public class BaseCanvas_Delegate {
-    // ---- delegate manager ----
-    protected static DelegateManager<BaseCanvas_Delegate> sManager =
-            new DelegateManager<>(BaseCanvas_Delegate.class);
-
-    // ---- delegate helper data ----
-    private final static boolean[] sBoolOut = new boolean[1];
-
-
-    // ---- delegate data ----
-    protected Bitmap_Delegate mBitmap;
-    protected GcSnapshot mSnapshot;
-
-    // ---- Public Helper methods ----
-
-    protected BaseCanvas_Delegate(Bitmap_Delegate bitmap) {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
-    }
-
-    protected BaseCanvas_Delegate() {
-        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
-    }
-
-    /**
-     * Disposes of the {@link Graphics2D} stack.
-     */
-    protected void dispose() {
-        mSnapshot.dispose();
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        BufferedImage image = bitmapDelegate.getImage();
-        float right = left + image.getWidth();
-        float bottom = top + image.getHeight();
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
-                0, 0, image.getWidth(), image.getHeight(),
-                (int)left, (int)top, (int)right, (int)bottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft, float srcTop,
-            float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
-            float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity) {
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, (int) srcLeft, (int) srcTop,
-                (int) srcRight, (int) srcBottom, (int) dstLeft, (int) dstTop, (int) dstRight,
-                (int) dstBottom);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmap(long nativeCanvas, int[] colors, int offset, int stride,
-            final float x, final float y, int width, int height, boolean hasAlpha,
-            long nativePaintOrZero) {
-        // create a temp BufferedImage containing the content.
-        final BufferedImage image = new BufferedImage(width, height,
-                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
-        image.setRGB(0, 0, width, height, colors, offset, stride);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    graphics.drawImage(image, (int) x, (int) y, null);
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawColor(long nativeCanvas, final int color, final int mode) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        final int w = canvasDelegate.mBitmap.getImage().getWidth();
-        final int h = canvasDelegate.mBitmap.getImage().getHeight();
-        draw(nativeCanvas, (graphics, paint) -> {
-            // reset its transform just in case
-            graphics.setTransform(new AffineTransform());
-
-            // set the color
-            graphics.setColor(new java.awt.Color(color, true /*alpha*/));
-
-            Composite composite = PorterDuffUtility.getComposite(
-                    PorterDuffUtility.getPorterDuffMode(mode), 0xFF);
-            if (composite != null) {
-                graphics.setComposite(composite);
-            }
-
-            graphics.fillRect(0, 0, w, h);
-        });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPaint(long nativeCanvas, long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPaint is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoint(long nativeCanvas, float x, float y,
-            long nativePaint) {
-        // TODO: need to support the attribute (e.g. stroke width) of paint
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.fillRect((int)x, (int)y, 1, 1));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawPoints(long nativeCanvas, float[] pts, int offset, int count,
-            long nativePaint) {
-        if (offset < 0 || count < 0 || offset + count > pts.length) {
-            throw new IllegalArgumentException("Invalid argument set");
-        }
-        // ignore the last point if the count is odd (It means it is not paired).
-        count = (count >> 1) << 1;
-        for (int i = offset; i < offset + count; i += 2) {
-            nDrawPoint(nativeCanvas, pts[i], pts[i + 1], nativePaint);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLine(long nativeCanvas,
-            final float startX, final float startY, final float stopX, final float stopY,
-            long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawLines(long nativeCanvas,
-            final float[] pts, final int offset, final int count,
-            long nativePaint) {
-        draw(nativeCanvas, nativePaint, false /*compositeOnly*/,
-                false /*forceSrcMode*/, (graphics, paintDelegate) -> {
-                    for (int i = 0; i < count; i += 4) {
-                        graphics.drawLine((int) pts[i + offset], (int) pts[i + offset + 1],
-                                (int) pts[i + offset + 2], (int) pts[i + offset + 3]);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom, long paint) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRect((int)left, (int)top,
-                                (int)(right-left), (int)(bottom-top));
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawOval(long nativeCanvas, final float left,
-            final float top, final float right, final float bottom, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fillOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.drawOval((int)left, (int)top,
-                                    (int)(right - left), (int)(bottom - top));
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawCircle(long nativeCanvas,
-            float cx, float cy, float radius, long paint) {
-        nDrawOval(nativeCanvas,
-                cx - radius, cy - radius, cx + radius, cy + radius,
-                paint);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawArc(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float startAngle, final float sweep,
-            final boolean useCenter, long paint) {
-        if (right > left && bottom > top) {
-            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                    (graphics, paintDelegate) -> {
-                        int style = paintDelegate.getStyle();
-
-                        Arc2D.Float arc = new Arc2D.Float(
-                                left, top, right - left, bottom - top,
-                                -startAngle, -sweep,
-                                useCenter ? Arc2D.PIE : Arc2D.OPEN);
-
-                        // draw
-                        if (style == Paint.Style.FILL.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.fill(arc);
-                        }
-
-                        if (style == Paint.Style.STROKE.nativeInt ||
-                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                            graphics.draw(arc);
-                        }
-                    });
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRoundRect(long nativeCanvas,
-            final float left, final float top, final float right, final float bottom,
-            final float rx, final float ry, long paint) {
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    int style = paintDelegate.getStyle();
-
-                    // draw
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fillRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.drawRoundRect(
-                                (int)left, (int)top,
-                                (int)(right - left), (int)(bottom - top),
-                                2 * (int)rx, 2 * (int)ry);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    public static void nDrawPath(long nativeCanvas, long path, long paint) {
-        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    Shape shape = pathDelegate.getJavaShape();
-                    Rectangle2D bounds = shape.getBounds2D();
-                    if (bounds.isEmpty()) {
-                        // Apple JRE 1.6 doesn't like drawing empty shapes.
-                        // http://b.android.com/178278
-
-                        if (pathDelegate.isEmpty()) {
-                            // This means that the path doesn't have any lines or curves so
-                            // nothing to draw.
-                            return;
-                        }
-
-                        // The stroke width is not consider for the size of the bounds so,
-                        // for example, a horizontal line, would be considered as an empty
-                        // rectangle.
-                        // If the strokeWidth is not 0, we use it to consider the size of the
-                        // path as well.
-                        float strokeWidth = paintDelegate.getStrokeWidth();
-                        if (strokeWidth <= 0.0f) {
-                            return;
-                        }
-                        bounds.setRect(bounds.getX(), bounds.getY(),
-                                Math.max(strokeWidth, bounds.getWidth()),
-                                Math.max(strokeWidth, bounds.getHeight()));
-                    }
-
-                    int style = paintDelegate.getStyle();
-
-                    if (style == Paint.Style.FILL.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.fill(shape);
-                    }
-
-                    if (style == Paint.Style.STROKE.nativeInt ||
-                            style == Paint.Style.FILL_AND_STROKE.nativeInt) {
-                        graphics.draw(shape);
-                    }
-                });
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawRegion(long nativeCanvas, long nativeRegion,
-            long nativePaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Some canvas paths may not be drawn", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawNinePatch(long nativeCanvas, long nativeBitmap, long ninePatch,
-            final float dstLeft, final float dstTop, final float dstRight, final float dstBottom,
-            long nativePaintOrZero, final int screenDensity, final int bitmapDensity) {
-
-        // get the delegate from the native int.
-        final Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        byte[] c = NinePatch_Delegate.getChunk(ninePatch);
-        if (c == null) {
-            // not a 9-patch?
-            BufferedImage image = bitmapDelegate.getImage();
-            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero, 0, 0, image.getWidth(),
-                    image.getHeight(), (int) dstLeft, (int) dstTop, (int) dstRight,
-                    (int) dstBottom);
-            return;
-        }
-
-        final NinePatchChunk chunkObject = NinePatch_Delegate.getChunk(c);
-        assert chunkObject != null;
-        if (chunkObject == null) {
-            return;
-        }
-
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // this one can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
-            @Override
-            public void draw(Graphics2D graphics, Paint_Delegate paint) {
-                chunkObject.draw(bitmapDelegate.getImage(), graphics, (int) dstLeft, (int) dstTop,
-                        (int) (dstRight - dstLeft), (int) (dstBottom - dstTop), screenDensity,
-                        bitmapDensity);
-            }
-        }, paintDelegate, true, false);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
-            long nMatrix, long nPaint) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the delegate from the native int, which can be null
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        // get the delegate from the native int.
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (bitmapDelegate == null) {
-            return;
-        }
-
-        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        final AffineTransform mtx = matrixDelegate.getAffineTransform();
-
-        canvasDelegate.getSnapshot().draw((graphics, paint) -> {
-            if (paint != null && paint.isFilterBitmap()) {
-                graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-            }
-
-            //FIXME add support for canvas, screen and bitmap densities.
-            graphics.drawImage(image, mtx, null);
-        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawBitmapMesh(long nCanvas, Bitmap bitmap,
-            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
-            int colorOffset, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawVertices(long nCanvas, int mode, int n,
-            float[] verts, int vertOffset,
-            float[] texs, int texOffset,
-            int[] colors, int colorOffset,
-            short[] indices, int indexOffset,
-            int indexCount, long nPaint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawVertices is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, char[] text, int index, int count,
-            float startX, float startY, int flags, long paint, long typeface) {
-        drawText(nativeCanvas, text, index, count, startX, startY, (flags & 1) != 0,
-                paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawText(long nativeCanvas, String text,
-            int start, int end, float x, float y, final int flags, long paint,
-            long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        nDrawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, String text,
-            int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        drawText(nativeCanvas, buffer, 0, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextRun(long nativeCanvas, char[] text,
-            int start, int count, int contextStart, int contextCount,
-            float x, float y, boolean isRtl, long paint, long typeface) {
-        drawText(nativeCanvas, text, start, count, x, y, isRtl, paint, typeface);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            char[] text, int index,
-            int count, long path,
-            float hOffset,
-            float vOffset, int bidiFlags,
-            long paint, long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nDrawTextOnPath(long nativeCanvas,
-            String text, long path,
-            float hOffset,
-            float vOffset,
-            int bidiFlags, long paint,
-            long typeface) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, long nPaint, boolean compositeOnly, boolean forceSrcMode,
-            GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint which can be null if nPaint is 0;
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
-
-        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
-    }
-
-    /**
-     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
-     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
-     * <p>Note that the drawable may actually be executed several times if there are
-     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
-     */
-    private static void draw(long nCanvas, GcSnapshot.Drawable drawable) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mSnapshot.draw(drawable);
-    }
-
-    private static void drawText(long nativeCanvas, final char[] text, final int index,
-            final int count, final float startX, final float startY, final boolean isRtl,
-            long paint, final long typeface) {
-
-        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
-                (graphics, paintDelegate) -> {
-                    // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
-                    // Any change to this method should be reflected in Paint.measureText
-
-                    // assert that the typeface passed is actually the one stored in paint.
-                    assert (typeface == paintDelegate.mNativeTypeface);
-
-                    // Paint.TextAlign indicates how the text is positioned relative to X.
-                    // LEFT is the default and there's nothing to do.
-                    float x = startX;
-                    int limit = index + count;
-                    if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
-                        RectF bounds =
-                                paintDelegate.measureText(text, index, count, null, 0, isRtl);
-                        float m = bounds.right - bounds.left;
-                        if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
-                            x -= m / 2;
-                        } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
-                            x -= m;
-                        }
-                    }
-
-                    new BidiRenderer(graphics, paintDelegate, text).setRenderLocation(x,
-                            startY).renderText(index, limit, isRtl, null, 0, true);
-                });
-    }
-
-    private static void drawBitmap(long nativeCanvas, Bitmap_Delegate bitmap,
-            long nativePaintOrZero, final int sleft, final int stop, final int sright,
-            final int sbottom, final int dleft, final int dtop, final int dright,
-            final int dbottom) {
-        // get the delegate from the native int.
-        BaseCanvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the paint, which could be null if the int is 0
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
-
-        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
-
-        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
-                (graphics, paint) -> {
-                    if (paint != null && paint.isFilterBitmap()) {
-                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-                    }
-
-                    //FIXME add support for canvas, screen and bitmap densities.
-                    graphics.drawImage(image, dleft, dtop, dright, dbottom, sleft, stop, sright,
-                            sbottom, null);
-                });
-    }
-
-    /**
-     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
-     * The image returns, through a 1-size boolean array, whether the drawing code should
-     * use a SRC composite no matter what the paint says.
-     *
-     * @param bitmap the bitmap
-     * @param paint the paint that will be used to draw
-     * @param forceSrcMode whether the composite will have to be SRC
-     * @return the image to draw
-     */
-    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
-            boolean[] forceSrcMode) {
-        BufferedImage image = bitmap.getImage();
-        forceSrcMode[0] = false;
-
-        // if the bitmap config is alpha_8, then we erase all color value from it
-        // before drawing it or apply the texture from the shader if present.
-        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
-            Shader_Delegate shader = paint.getShader();
-            java.awt.Paint javaPaint = null;
-            if (shader instanceof BitmapShader_Delegate) {
-                javaPaint = shader.getJavaPaint();
-            }
-
-            fixAlpha8Bitmap(image, javaPaint);
-        } else if (!bitmap.hasAlpha()) {
-            // hasAlpha is merely a rendering hint. There can in fact be alpha values
-            // in the bitmap but it should be ignored at drawing time.
-            // There is two ways to do this:
-            // - override the composite to be SRC. This can only be used if the composite
-            //   was going to be SRC or SRC_OVER in the first place
-            // - Create a different bitmap to draw in which all the alpha channel values is set
-            //   to 0xFF.
-            if (paint != null) {
-                PorterDuff.Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-
-                forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER || mode == PorterDuff.Mode.SRC;
-            }
-
-            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
-            if (!forceSrcMode[0]) {
-                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
-            }
-        }
-
-        return image;
-    }
-
-    /**
-     * This method will apply the correct color to the passed "only alpha" image. Colors on the
-     * passed image will be destroyed.
-     * If the passed javaPaint is null, the color will be set to 0. If a paint is passed, it will
-     * be used to obtain the color that will be applied.
-     * <p/>
-     * This will destroy the passed image color channel.
-     */
-    private static void fixAlpha8Bitmap(final BufferedImage image,
-            @Nullable java.awt.Paint javaPaint) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        DataBuffer texture = null;
-        if (javaPaint != null) {
-            PaintContext context = javaPaint.createContext(ColorModel.getRGBdefault(), null, null,
-                    new AffineTransform(), null);
-            texture = context.getRaster(0, 0, w, h).getDataBuffer();
-        }
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        final int length = argb.length;
-        for (int i = 0; i < length; i++) {
-            argb[i] &= 0xFF000000;
-            if (texture != null) {
-                argb[i] |= texture.getElem(i) & 0x00FFFFFF;
-            }
-        }
-
-        image.setRGB(0, 0, w, h, argb, 0, w);
-    }
-
-    protected int save(int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.save(saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    protected int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
-        Paint_Delegate paint = new Paint_Delegate();
-        paint.setAlpha(alpha);
-        return saveLayer(rect, paint, saveFlags);
-    }
-
-    protected int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
-        // get the current save count
-        int count = mSnapshot.size();
-
-        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
-
-        // return the old save count
-        return count;
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>
-     * @param saveCount the saveCount
-     */
-    protected void restoreTo(int saveCount) {
-        mSnapshot = mSnapshot.restoreTo(saveCount);
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}
-     */
-    protected void restore() {
-        mSnapshot = mSnapshot.restore();
-    }
-
-    protected boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
deleted file mode 100644
index c6827a3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Paint_Delegate.FontInfo;
-import android.icu.lang.UScript;
-import android.icu.lang.UScriptRun;
-import android.icu.text.Bidi;
-import android.icu.text.BidiRun;
-
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Render the text by breaking it into various scripts and using the right font for each script.
- * Can be used to measure the text without actually drawing it.
- */
-@SuppressWarnings("deprecation")
-public class BidiRenderer {
-    private static String JAVA_VENDOR = System.getProperty("java.vendor");
-
-    private static class ScriptRun {
-        int start;
-        int limit;
-        boolean isRtl;
-        int scriptCode;
-        Font font;
-
-        public ScriptRun(int start, int limit, boolean isRtl) {
-            this.start = start;
-            this.limit = limit;
-            this.isRtl = isRtl;
-            this.scriptCode = UScript.INVALID_CODE;
-        }
-    }
-
-    private final Graphics2D mGraphics;
-    private final Paint_Delegate mPaint;
-    private char[] mText;
-    // This List can contain nulls. A null font implies that the we weren't able to load the font
-    // properly. So, if we encounter a situation where we try to use that font, log a warning.
-    private List<Font> mFonts;
-    // Bounds of the text drawn so far.
-    private RectF mBounds;
-    private float mBaseline;
-
-    /**
-     * @param graphics May be null.
-     * @param paint The Paint to use to get the fonts. Should not be null.
-     * @param text Unidirectional text. Should not be null.
-     */
-    public BidiRenderer(Graphics2D graphics, Paint_Delegate paint, char[] text) {
-        assert (paint != null);
-        mGraphics = graphics;
-        mPaint = paint;
-        mText = text;
-        mFonts = new ArrayList<Font>(paint.getFonts().size());
-        for (FontInfo fontInfo : paint.getFonts()) {
-            if (fontInfo == null) {
-                mFonts.add(null);
-                continue;
-            }
-            mFonts.add(fontInfo.mFont);
-        }
-        mBounds = new RectF();
-    }
-
-    /**
-     *
-     * @param x The x-coordinate of the left edge of where the text should be drawn on the given
-     *            graphics.
-     * @param y The y-coordinate at which to draw the text on the given mGraphics.
-     *
-     */
-    public BidiRenderer setRenderLocation(float x, float y) {
-        mBounds = new RectF(x, y, x, y);
-        mBaseline = y;
-        return this;
-    }
-
-    /**
-     * Perform Bidi Analysis on the text and then render it.
-     * <p/>
-     * To skip the analysis and render unidirectional text, see {@link
-     * #renderText(int, int, boolean, float[], int, boolean)}
-     */
-    public RectF renderText(int start, int limit, int bidiFlags, float[] advances,
-            int advancesIndex, boolean draw) {
-        Bidi bidi = new Bidi(mText, start, null, 0, limit - start, getIcuFlags(bidiFlags));
-        for (int i = 0; i < bidi.countRuns(); i++) {
-            BidiRun visualRun = bidi.getVisualRun(i);
-            boolean isRtl = visualRun.getDirection() == Bidi.RTL;
-            renderText(visualRun.getStart(), visualRun.getLimit(), isRtl, advances,
-                    advancesIndex, draw);
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render unidirectional text.
-     * <p/>
-     * This method can also be used to measure the width of the text without actually drawing it.
-     * <p/>
-     * @param start index of the first character
-     * @param limit index of the first character that should not be rendered.
-     * @param isRtl is the text right-to-left
-     * @param advances If not null, then advances for each character to be rendered are returned
-     *            here.
-     * @param advancesIndex index into advances from where the advances need to be filled.
-     * @param draw If true and {@code graphics} is not null, draw the rendered text on the graphics
-     *            at the given co-ordinates
-     * @return A rectangle specifying the bounds of the text drawn.
-     */
-    public RectF renderText(int start, int limit, boolean isRtl, float[] advances,
-            int advancesIndex, boolean draw) {
-        // We break the text into scripts and then select font based on it and then render each of
-        // the script runs.
-        for (ScriptRun run : getScriptRuns(mText, start, limit, isRtl, mFonts)) {
-            int flag = Font.LAYOUT_NO_LIMIT_CONTEXT | Font.LAYOUT_NO_START_CONTEXT;
-            flag |= isRtl ? Font.LAYOUT_RIGHT_TO_LEFT : Font.LAYOUT_LEFT_TO_RIGHT;
-            renderScript(run.start, run.limit, run.font, flag, advances, advancesIndex, draw);
-            advancesIndex += run.limit - run.start;
-        }
-        return mBounds;
-    }
-
-    /**
-     * Render a script run to the right of the bounds passed. Use the preferred font to render as
-     * much as possible. This also implements a fallback mechanism to render characters that cannot
-     * be drawn using the preferred font.
-     */
-    private void renderScript(int start, int limit, Font preferredFont, int flag,
-            float[] advances, int advancesIndex, boolean draw) {
-        if (mFonts.size() == 0 || preferredFont == null) {
-            return;
-        }
-
-        while (start < limit) {
-            boolean foundFont = false;
-            int canDisplayUpTo = preferredFont.canDisplayUpTo(mText, start, limit);
-            if (canDisplayUpTo == -1) {
-                // We can draw all characters in the text.
-                render(start, limit, preferredFont, flag, advances, advancesIndex, draw);
-                return;
-            }
-            if (canDisplayUpTo > start) {
-                // We can draw something.
-                render(start, canDisplayUpTo, preferredFont, flag, advances, advancesIndex, draw);
-                advancesIndex += canDisplayUpTo - start;
-                start = canDisplayUpTo;
-            }
-
-            // The current character cannot be drawn with the preferred font. Cycle through all the
-            // fonts to check which one can draw it.
-            int charCount = Character.isHighSurrogate(mText[start]) ? 2 : 1;
-            for (Font font : mFonts) {
-                if (font == null) {
-                    logFontWarning();
-                    continue;
-                }
-                canDisplayUpTo = font.canDisplayUpTo(mText, start, start + charCount);
-                if (canDisplayUpTo == -1) {
-                    render(start, start+charCount, font, flag, advances, advancesIndex, draw);
-                    start += charCount;
-                    advancesIndex += charCount;
-                    foundFont = true;
-                    break;
-                }
-            }
-            if (!foundFont) {
-                // No font can display this char. Use the preferred font. The char will most
-                // probably appear as a box or a blank space. We could, probably, use some
-                // heuristics and break the character into the base character and diacritics and
-                // then draw it, but it's probably not worth the effort.
-                render(start, start + charCount, preferredFont, flag, advances, advancesIndex,
-                        draw);
-                start += charCount;
-                advancesIndex += charCount;
-            }
-        }
-    }
-
-    private static void logFontWarning() {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                "Some fonts could not be loaded. The rendering may not be perfect. " +
-                        "Try running the IDE with JRE 7.", null, null);
-    }
-
-    /**
-     * Renders the text to the right of the bounds with the given font.
-     * @param font The font to render the text with.
-     */
-    private void render(int start, int limit, Font font, int flag, float[] advances,
-            int advancesIndex, boolean draw) {
-
-        FontRenderContext frc;
-        if (mGraphics != null) {
-            frc = mGraphics.getFontRenderContext();
-        } else {
-            frc = Toolkit.getDefaultToolkit().getFontMetrics(font).getFontRenderContext();
-
-            // Metrics obtained this way don't have anti-aliasing set. So,
-            // we create a new FontRenderContext with anti-aliasing set.
-            AffineTransform transform = font.getTransform();
-            if (mPaint.isAntiAliased() &&
-                    // Workaround for http://b.android.com/211659
-                    (transform.getScaleX() <= 9.9 ||
-                    !"JetBrains s.r.o".equals(JAVA_VENDOR))) {
-                frc = new FontRenderContext(transform, true, frc.usesFractionalMetrics());
-            }
-        }
-        GlyphVector gv = font.layoutGlyphVector(frc, mText, start, limit, flag);
-        int ng = gv.getNumGlyphs();
-        int[] ci = gv.getGlyphCharIndices(0, ng, null);
-        if (advances != null) {
-            for (int i = 0; i < ng; i++) {
-                int adv_idx = advancesIndex + ci[i];
-                advances[adv_idx] += gv.getGlyphMetrics(i).getAdvanceX();
-            }
-        }
-        if (draw && mGraphics != null) {
-            mGraphics.drawGlyphVector(gv, mBounds.right, mBaseline);
-        }
-
-        // Update the bounds.
-        Rectangle2D awtBounds = gv.getLogicalBounds();
-        RectF bounds = awtRectToAndroidRect(awtBounds, mBounds.right, mBaseline);
-        // If the width of the bounds is zero, no text had been drawn earlier. Hence, use the
-        // coordinates from the bounds as an offset.
-        if (Math.abs(mBounds.right - mBounds.left) == 0) {
-            mBounds = bounds;
-        } else {
-            mBounds.union(bounds);
-        }
-    }
-
-    // --- Static helper methods ---
-
-    private static RectF awtRectToAndroidRect(Rectangle2D awtRec, float offsetX, float offsetY) {
-        float left = (float) awtRec.getX();
-        float top = (float) awtRec.getY();
-        float right = (float) (left + awtRec.getWidth());
-        float bottom = (float) (top + awtRec.getHeight());
-        RectF androidRect = new RectF(left, top, right, bottom);
-        androidRect.offset(offsetX, offsetY);
-        return androidRect;
-    }
-
-    /* package */  static List<ScriptRun> getScriptRuns(char[] text, int start, int limit,
-            boolean isRtl, List<Font> fonts) {
-        LinkedList<ScriptRun> scriptRuns = new LinkedList<ScriptRun>();
-
-        int count = limit - start;
-        UScriptRun uScriptRun = new UScriptRun(text, start, count);
-        while (uScriptRun.next()) {
-            int scriptStart = uScriptRun.getScriptStart();
-            int scriptLimit = uScriptRun.getScriptLimit();
-            ScriptRun run = new ScriptRun(scriptStart, scriptLimit, isRtl);
-            run.scriptCode = uScriptRun.getScriptCode();
-            setScriptFont(text, run, fonts);
-            scriptRuns.add(run);
-        }
-
-        return scriptRuns;
-    }
-
-    // TODO: Replace this method with one which returns the font based on the scriptCode.
-    private static void setScriptFont(char[] text, ScriptRun run,
-            List<Font> fonts) {
-        for (Font font : fonts) {
-            if (font == null) {
-                logFontWarning();
-                continue;
-            }
-            if (font.canDisplayUpTo(text, run.start, run.limit) == -1) {
-                run.font = font;
-                return;
-            }
-        }
-        run.font = fonts.get(0);
-    }
-
-    private static int getIcuFlags(int bidiFlag) {
-        switch (bidiFlag) {
-            case Paint.BIDI_LTR:
-            case Paint.BIDI_FORCE_LTR:
-                return Bidi.DIRECTION_LEFT_TO_RIGHT;
-            case Paint.BIDI_RTL:
-            case Paint.BIDI_FORCE_RTL:
-                return Bidi.DIRECTION_RIGHT_TO_LEFT;
-            case Paint.BIDI_DEFAULT_LTR:
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-            case Paint.BIDI_DEFAULT_RTL:
-                return Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
-            default:
-                assert false;
-                return Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
deleted file mode 100644
index 8bd2a7a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import com.android.layoutlib.bridge.util.NinePatchInputStream;
-import android.graphics.BitmapFactory.Options;
-import android.graphics.Bitmap_Delegate.BitmapCreateFlags;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapFactory
- *
- * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-/*package*/ class BitmapFactory_Delegate {
-
-    // ------ Native Delegates ------
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            @Nullable Rect padding, @Nullable Options opts) {
-        Bitmap bm = null;
-
-        Density density = Density.MEDIUM;
-        Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE);
-        if (opts != null) {
-            density = Density.getEnum(opts.inDensity);
-            if (opts.inPremultiplied) {
-                bitmapCreateFlags.add(BitmapCreateFlags.PREMULTIPLIED);
-            }
-            opts.inScaled = false;
-        }
-
-        try {
-            if (is instanceof NinePatchInputStream) {
-                NinePatchInputStream npis = (NinePatchInputStream) is;
-                npis.disableFakeMarkSupport();
-
-                // load the bitmap as a nine patch
-                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
-                        npis, true /*is9Patch*/, false /*convert*/);
-
-                // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
-                        density);
-                NinePatchChunk chunk = ninePatch.getChunk();
-
-                // put the chunk in the bitmap
-                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
-
-                if (padding != null) {
-                    // read the padding
-                    int[] paddingArray = chunk.getPadding();
-                    padding.left = paddingArray[0];
-                    padding.top = paddingArray[1];
-                    padding.right = paddingArray[2];
-                    padding.bottom = paddingArray[3];
-                }
-            } else {
-                // load the bitmap directly.
-                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
-            }
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to load image", e, null);
-        }
-
-        return bm;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
-            Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeAsset(long asset, Rect padding, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
-            int length, Options opts) {
-        opts.inBitmap = null;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) {
-        return true;
-    }
-
-    /**
-     * Set the newly decoded bitmap's density based on the Options.
-     *
-     * Copied from {@link BitmapFactory#setDensityFromOptions(Bitmap, Options)}.
-     */
-    @LayoutlibDelegate
-    /*package*/ static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
-        if (outputBitmap == null || opts == null) return;
-
-        final int density = opts.inDensity;
-        if (density != 0) {
-            outputBitmap.setDensity(density);
-            final int targetDensity = opts.inTargetDensity;
-            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
-                return;
-            }
-
-            // --- Change from original implementation begins ---
-            // LayoutLib doesn't scale the nine patch when decoding it. Hence, don't change the
-            // density of the source bitmap in case of ninepatch.
-
-            if (opts.inScaled) {
-            // --- Change from original implementation ends. ---
-                outputBitmap.setDensity(targetDensity);
-            }
-        } else if (opts.inBitmap != null) {
-            // bitmap was reused, ensure density is reset
-            outputBitmap.setDensity(Bitmap.getDefaultDensity());
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
deleted file mode 100644
index 4914a48..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.PaintContext;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.Raster;
-
-/**
- * Delegate implementing the native methods of android.graphics.BitmapShader
- *
- * Through the layoutlib_create tool, the original native methods of BitmapShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BitmapShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class BitmapShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, Bitmap androidBitmap,
-            int shaderTileModeX, int shaderTileModeY) {
-        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
-        if (bitmap == null) {
-            return 0;
-        }
-
-        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(nativeMatrix,
-                bitmap.getImage(),
-                Shader_Delegate.getTileMode(shaderTileModeX),
-                Shader_Delegate.getTileMode(shaderTileModeY));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private BitmapShader_Delegate(long matrix, BufferedImage image,
-            TileMode tileModeX, TileMode tileModeY) {
-        super(matrix);
-        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
-    }
-
-    private class BitmapShaderPaint implements java.awt.Paint {
-        private final BufferedImage mImage;
-        private final TileMode mTileModeX;
-        private final TileMode mTileModeY;
-
-        BitmapShaderPaint(BufferedImage image,
-                TileMode tileModeX, TileMode tileModeY) {
-            mImage = image;
-            mTileModeX = tileModeX;
-            mTileModeY = tileModeY;
-        }
-
-        @Override
-        public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds,
-                Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
-            AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                canvasMatrix = new AffineTransform();
-            }
-
-            AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
-                localMatrix = new AffineTransform();
-            }
-
-            if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
-                // Fallback to the default ARGB color model
-                colorModel = ColorModel.getRGBdefault();
-            }
-
-            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class BitmapShaderContext implements PaintContext {
-
-            private final AffineTransform mCanvasMatrix;
-            private final AffineTransform mLocalMatrix;
-            private final ColorModel mColorModel;
-
-            public BitmapShaderContext(
-                    AffineTransform canvasMatrix,
-                    AffineTransform localMatrix,
-                    ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public Raster getRaster(int x, int y, int w, int h) {
-                BufferedImage image = new BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float fx, float fy) {
-            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
-            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
-
-            return mImage.getRGB(x, y);
-        }
-
-        private int getCoordinate(int i, int size, TileMode mode) {
-            if (i < 0) {
-                switch (mode) {
-                    case CLAMP:
-                        i = 0;
-                        break;
-                    case REPEAT:
-                        i = size - 1 - (-i % size);
-                        break;
-                    case MIRROR:
-                        // this is the same as the positive side, just make the value positive
-                        // first.
-                        i = -i;
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            } else if (i >= size) {
-                switch (mode) {
-                    case CLAMP:
-                        i = size - 1;
-                        break;
-                    case REPEAT:
-                        i = i % size;
-                        break;
-                    case MIRROR:
-                        int count = i / size;
-                        i = i % size;
-
-                        if ((count % 2) == 1) {
-                            i = size - 1 - i;
-                        }
-                        break;
-                }
-            }
-
-            return i;
-        }
-
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
deleted file mode 100644
index 0064537..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-import android.os.Parcel;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Set;
-
-import javax.imageio.ImageIO;
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Bitmap
- *
- * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Bitmap class.
- *
- * @see DelegateManager
- *
- */
-public final class Bitmap_Delegate {
-
-
-    public enum BitmapCreateFlags {
-        NONE, PREMULTIPLIED, MUTABLE
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Bitmap_Delegate> sManager =
-            new DelegateManager<>(Bitmap_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private final Config mConfig;
-    private final BufferedImage mImage;
-    private boolean mHasAlpha = true;
-    private boolean mHasMipMap = false;      // TODO: check the default.
-    private boolean mIsPremultiplied = true;
-    private int mGenerationId = 0;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
-     */
-    public static Bitmap_Delegate getDelegate(long native_bitmap) {
-        return sManager.getDelegate(native_bitmap);
-    }
-
-    @Nullable
-    public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
-        return bitmap == null ? null : getDelegate(bitmap.getNativeInstance());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given file content.
-     *
-     * @param input the file from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    private static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the file.
-        BufferedImage image = ImageIO.read(input);
-        if (image == null && input.exists()) {
-            // There was a problem decoding the image, or the decoder isn't registered. Webp maybe.
-            // Replace with a broken image icon.
-            BridgeContext currentContext = RenderAction.getCurrentContext();
-            if (currentContext != null) {
-                RenderResources resources = currentContext.getRenderResources();
-                ResourceValue broken = resources.getFrameworkResource(ResourceType.DRAWABLE,
-                        "ic_menu_report_image");
-                File brokenFile = new File(broken.getValue());
-                if (brokenFile.exists()) {
-                    image = ImageIO.read(brokenFile);
-                }
-            }
-        }
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
-            throws IOException {
-        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given stream content.
-     *
-     * @param input the stream from which to read the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
-            Density density) throws IOException {
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param isMutable whether the bitmap is mutable
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) {
-        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
-    }
-
-    /**
-     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
-     *
-     * @param image the bitmap content
-     * @param density the density associated with the bitmap
-     *
-     * @see Bitmap#isPremultiplied()
-     * @see Bitmap#isMutable()
-     * @see Bitmap#getDensity()
-     */
-    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
-            Density density) {
-        // create a delegate with the given image.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
-
-        return createBitmap(delegate, createFlags, density.getDpiValue());
-    }
-
-    private static int getBufferedImageType() {
-        return BufferedImage.TYPE_INT_ARGB;
-    }
-
-    /**
-     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
-     */
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    /**
-     * Returns the Android bitmap config. Note that this not the config of the underlying
-     * Java2D bitmap.
-     */
-    public Config getConfig() {
-        return mConfig;
-    }
-
-    /**
-     * Returns the hasAlpha rendering hint
-     * @return true if the bitmap alpha should be used at render time
-     */
-    public boolean hasAlpha() {
-        return mHasAlpha && mConfig != Config.RGB_565;
-    }
-
-    /**
-     * Update the generationId.
-     *
-     * @see Bitmap#getGenerationId()
-     */
-    public void change() {
-        mGenerationId++;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
-            int height, int nativeConfig, boolean isMutable, @Nullable float[] xyzD50,
-            @Nullable ColorSpace.Rgb.TransferParameters p) {
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        if (colors != null) {
-            image.setRGB(0, 0, width, height, colors, offset, stride);
-        }
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                            Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        int width = srcImage.getWidth();
-        int height = srcImage.getHeight();
-
-        int imageType = getBufferedImageType();
-
-        // create the image
-        BufferedImage image = new BufferedImage(width, height, imageType);
-
-        // copy the source image into the image.
-        int[] argb = new int[width * height];
-        srcImage.getRGB(0, 0, width, height, argb, 0, width);
-        image.setRGB(0, 0, width, height, argb, 0, width);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
-
-        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmem(long nativeSrcBitmap) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) {
-        // Unused method; no implementation provided.
-        assert false;
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetNativeFinalizer() {
-        synchronized (Bitmap_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-            return sFinalizer;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeRecycle(long nativeBitmap) {
-        // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap.
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height,
-            int config, boolean isPremultiplied) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.reconfigure() is not supported", null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
-            OutputStream stream, byte[] tempStorage) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.compress() is not supported", null /*data*/);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeErase(long nativeBitmap, int color) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        BufferedImage image = delegate.mImage;
-
-        Graphics2D g = image.createGraphics();
-        try {
-            g.setColor(new java.awt.Color(color, true));
-
-            g.fillRect(0, 0, image.getWidth(), image.getHeight());
-        } finally {
-            g.dispose();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeRowBytes(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getWidth();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeConfig(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mConfig.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasAlpha;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate == null || delegate.mHasMipMap;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mImage.getRGB(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, color);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset,
-            int stride, int x, int y, int width, int height) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
-        // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGenerationId(long nativeBitmap) {
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mGenerationId;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
-        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
-                null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable,
-            int density, Parcel p) {
-        // This is only called when sending a bitmap through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint,
-            int[] offsetXY) {
-        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
-        if (bitmap == null) {
-            return null;
-        }
-
-        // get the paint which can be null if nativePaint is 0.
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-
-        if (paint != null && paint.getMaskFilter() != null) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    "MaskFilter not supported in Bitmap.extractAlpha",
-                    null, null /*data*/);
-        }
-
-        int alpha = paint != null ? paint.getAlpha() : 0xFF;
-        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
-
-        // create the delegate. The actual Bitmap config is only an alpha channel
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
-
-        // the density doesn't matter, it's set by the Java method.
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
-                Density.DEFAULT_DENSITY /*density*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        return delegate != null && delegate.mIsPremultiplied;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mIsPremultiplied = isPremul;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha,
-            boolean isPremul) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasAlpha = hasAlpha;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHasMipMap = hasMipMap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSameAs(long nb0, long nb1) {
-        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
-        if (delegate1 == null) {
-            return false;
-        }
-
-        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
-        if (delegate2 == null) {
-            return false;
-        }
-
-        BufferedImage image1 = delegate1.getImage();
-        BufferedImage image2 = delegate2.getImage();
-        if (delegate1.mConfig != delegate2.mConfig ||
-                image1.getWidth() != image2.getWidth() ||
-                image1.getHeight() != image2.getHeight()) {
-            return false;
-        }
-
-        // get the internal data
-        int w = image1.getWidth();
-        int h = image2.getHeight();
-        int[] argb1 = new int[w*h];
-        int[] argb2 = new int[w*h];
-
-        image1.getRGB(0, 0, w, h, argb1, 0, w);
-        image2.getRGB(0, 0, w, h, argb2, 0, w);
-
-        // compares
-        if (delegate1.mConfig == Config.ALPHA_8) {
-            // in this case we have to manually compare the alpha channel as the rest is garbage.
-            final int length = w*h;
-            for (int i = 0 ; i < length ; i++) {
-                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        return Arrays.equals(argb1, argb2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetAllocationByteCount(long nativeBitmap) {
-        // get the delegate from the native int.
-        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
-        if (delegate == null) {
-            return 0;
-        }
-        return nativeRowBytes(nativeBitmap) * delegate.mImage.getHeight();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
-        // do nothing as Bitmap_Delegate does not have caches
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) {
-        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(nativeBitmap);
-        if (srcBmpDelegate == null) {
-            return null;
-        }
-
-        BufferedImage srcImage = srcBmpDelegate.getImage();
-
-        // create the image
-        BufferedImage image = new BufferedImage(srcImage.getColorModel(), srcImage.copyData(null),
-                srcImage.isAlphaPremultiplied(), null);
-
-        // create a delegate with the content of the stream.
-        Bitmap_Delegate delegate = new Bitmap_Delegate(image, srcBmpDelegate.getConfig());
-
-        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE),
-                Bitmap.getDefaultDensity());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeIsSRGB(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeCopyColorSpace(long srcBitmap, long dstBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Color spaces are not supported", null /*data*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private Bitmap_Delegate(BufferedImage image, Config config) {
-        mImage = image;
-        mConfig = config;
-    }
-
-    private static Bitmap createBitmap(Bitmap_Delegate delegate,
-            Set<BitmapCreateFlags> createFlags, int density) {
-        // get its native_int
-        long nativeInt = sManager.addNewDelegate(delegate);
-
-        int width = delegate.mImage.getWidth();
-        int height = delegate.mImage.getHeight();
-        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
-        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
-
-        // and create/return a new Bitmap with it
-        return new Bitmap(nativeInt, width, height, density, isMutable,
-                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
-    }
-
-    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
-        Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
-        if (isMutable) {
-            createFlags.add(BitmapCreateFlags.MUTABLE);
-        }
-        return createFlags;
-    }
-
-    /**
-     * Creates and returns a copy of a given BufferedImage.
-     * <p/>
-     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
-     *
-     * @param image the image to copy
-     * @param imageType the type of the new image
-     * @param alpha an optional alpha modifier
-     * @return a new BufferedImage
-     */
-    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
-        int w = image.getWidth();
-        int h = image.getHeight();
-
-        BufferedImage result = new BufferedImage(w, h, imageType);
-
-        int[] argb = new int[w * h];
-        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
-
-        if (alpha != 255) {
-            final int length = argb.length;
-            for (int i = 0 ; i < length; i++) {
-                int a = (argb[i] >>> 24 * alpha) / 255;
-                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
-            }
-        }
-
-        result.setRGB(0, 0, w, h, argb, 0, w);
-
-        return result;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java b/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
deleted file mode 100644
index 5cc964a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlendComposite.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.Composite;
-import java.awt.CompositeContext;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-
-/*
- * (non-Javadoc)
- * The class is adapted from a demo tool for Blending Modes written by
- * Romain Guy (romainguy@android.com). The tool is available at
- * http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/
- *
- * This class has been adapted for applying color filters. When applying color filters, the src
- * image should not extend beyond the dest image, but in our implementation of the filters, it does.
- * To compensate for the effect, we recompute the alpha value of the src image before applying
- * the color filter as it should have been applied.
- */
-public final class BlendComposite implements Composite {
-    public enum BlendingMode {
-        MULTIPLY(),
-        SCREEN(),
-        DARKEN(),
-        LIGHTEN(),
-        OVERLAY(),
-        ADD();
-
-        private final BlendComposite mComposite;
-
-        BlendingMode() {
-            mComposite = new BlendComposite(this);
-        }
-
-        BlendComposite getBlendComposite() {
-            return mComposite;
-        }
-    }
-
-    private float alpha;
-    private BlendingMode mode;
-
-    private BlendComposite(BlendingMode mode) {
-        this(mode, 1.0f);
-    }
-
-    private BlendComposite(BlendingMode mode, float alpha) {
-        this.mode = mode;
-        setAlpha(alpha);
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode) {
-        return mode.getBlendComposite();
-    }
-
-    public static BlendComposite getInstance(BlendingMode mode, float alpha) {
-        if (alpha > 0.9999f) {
-            return getInstance(mode);
-        }
-        return new BlendComposite(mode, alpha);
-    }
-
-    public float getAlpha() {
-        return alpha;
-    }
-
-    public BlendingMode getMode() {
-        return mode;
-    }
-
-    private void setAlpha(float alpha) {
-        if (alpha < 0.0f || alpha > 1.0f) {
-            assert false : "alpha must be comprised between 0.0f and 1.0f";
-            alpha = Math.min(alpha, 1.0f);
-            alpha = Math.max(alpha, 0.0f);
-        }
-
-        this.alpha = alpha;
-    }
-
-    @Override
-    public int hashCode() {
-        return Float.floatToIntBits(alpha) * 31 + mode.ordinal();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof BlendComposite)) {
-            return false;
-        }
-
-        BlendComposite bc = (BlendComposite) obj;
-
-        return mode == bc.mode && alpha == bc.alpha;
-    }
-
-    public CompositeContext createContext(ColorModel srcColorModel,
-                                          ColorModel dstColorModel,
-                                          RenderingHints hints) {
-        return new BlendingContext(this);
-    }
-
-    private static final class BlendingContext implements CompositeContext {
-        private final Blender blender;
-        private final BlendComposite composite;
-
-        private BlendingContext(BlendComposite composite) {
-            this.composite = composite;
-            this.blender = Blender.getBlenderFor(composite);
-        }
-
-        public void dispose() {
-        }
-
-        public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
-            if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT ||
-                dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
-                throw new IllegalStateException(
-                        "Source and destination must store pixels as INT.");
-            }
-
-            int width = Math.min(src.getWidth(), dstIn.getWidth());
-            int height = Math.min(src.getHeight(), dstIn.getHeight());
-
-            float alpha = composite.getAlpha();
-
-            int[] srcPixel = new int[4];
-            int[] dstPixel = new int[4];
-            int[] result = new int[4];
-            int[] srcPixels = new int[width];
-            int[] dstPixels = new int[width];
-
-            for (int y = 0; y < height; y++) {
-                dstIn.getDataElements(0, y, width, 1, dstPixels);
-                if (alpha != 0) {
-                    src.getDataElements(0, y, width, 1, srcPixels);
-                    for (int x = 0; x < width; x++) {
-                        // pixels are stored as INT_ARGB
-                        // our arrays are [R, G, B, A]
-                        int pixel = srcPixels[x];
-                        srcPixel[0] = (pixel >> 16) & 0xFF;
-                        srcPixel[1] = (pixel >>  8) & 0xFF;
-                        srcPixel[2] = (pixel      ) & 0xFF;
-                        srcPixel[3] = (pixel >> 24) & 0xFF;
-
-                        pixel = dstPixels[x];
-                        dstPixel[0] = (pixel >> 16) & 0xFF;
-                        dstPixel[1] = (pixel >>  8) & 0xFF;
-                        dstPixel[2] = (pixel      ) & 0xFF;
-                        dstPixel[3] = (pixel >> 24) & 0xFF;
-
-                        // ---- Modified from original ----
-                        // recompute src pixel for transparency.
-                        srcPixel[3] *= dstPixel[3] / 0xFF;
-                        // ---- Modification ends ----
-
-                        result = blender.blend(srcPixel, dstPixel, result);
-
-                        // mixes the result with the opacity
-                        if (alpha == 1) {
-                            dstPixels[x] = (result[3] & 0xFF) << 24 |
-                                           (result[0] & 0xFF) << 16 |
-                                           (result[1] & 0xFF) <<  8 |
-                                           result[2] & 0xFF;
-                        } else {
-                            dstPixels[x] =
-                                    ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 |
-                                    ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 |
-                                    ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) <<  8 |
-                                    (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF;
-                        }
-
-                    }
-            }
-                dstOut.setDataElements(0, y, width, 1, dstPixels);
-            }
-        }
-    }
-
-    private static abstract class Blender {
-        public abstract int[] blend(int[] src, int[] dst, int[] result);
-
-        public static Blender getBlenderFor(BlendComposite composite) {
-            switch (composite.getMode()) {
-                case ADD:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 4; i++) {
-                                result[i] = Math.min(255, src[i] + dst[i]);
-                            }
-                            return result;
-                        }
-                    };
-                case DARKEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.min(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case LIGHTEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = Math.max(src[i], dst[i]);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case MULTIPLY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = (src[i] * dst[i]) >> 8;
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3] - (src[3] * dst[3]) / 255);
-                            return result;
-                        }
-                    };
-                case OVERLAY:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            for (int i = 0; i < 3; i++) {
-                                result[i] = dst[i] < 128 ? dst[i] * src[i] >> 7 :
-                                    255 - ((255 - dst[i]) * (255 - src[i]) >> 7);
-                            }
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                case SCREEN:
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = 255 - ((255 - src[0]) * (255 - dst[0]) >> 8);
-                            result[1] = 255 - ((255 - src[1]) * (255 - dst[1]) >> 8);
-                            result[2] = 255 - ((255 - src[2]) * (255 - dst[2]) >> 8);
-                            result[3] = Math.min(255, src[3] + dst[3]);
-                            return result;
-                        }
-                    };
-                default:
-                    assert false : "Blender not implement for " + composite.getMode().name();
-
-                    // Ignore the blend
-                    return new Blender() {
-                        @Override
-                        public int[] blend(int[] src, int[] dst, int[] result) {
-                            result[0] = dst[0];
-                            result[1] = dst[1];
-                            result[2] = dst[2];
-                            result[3] = dst[3];
-                            return result;
-                        }
-                    };
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
deleted file mode 100644
index d2569c7..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.BlurMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of BlurMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original BlurMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class BlurMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Blur Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float radius, int style) {
-        BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
deleted file mode 100644
index 47216ee..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.graphics.Bitmap.Config;
-
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-
-/**
- * Delegate implementing the native methods of android.graphics.Canvas
- *
- * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Canvas class.
- *
- * @see DelegateManager
- *
- */
-public final class Canvas_Delegate extends BaseCanvas_Delegate {
-
-    // ---- delegate manager ----
-    private static long sFinalizer = -1;
-
-    private DrawFilter_Delegate mDrawFilter = null;
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Returns the native delegate associated to a given {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(Canvas canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(canvas.getNativeCanvasWrapper());
-    }
-
-    /**
-     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
-     */
-    public static Canvas_Delegate getDelegate(long native_canvas) {
-        return (Canvas_Delegate) sManager.getDelegate(native_canvas);
-    }
-
-    /**
-     * Returns the current {@link Graphics2D} used to draw.
-     */
-    public GcSnapshot getSnapshot() {
-        return mSnapshot;
-    }
-
-    /**
-     * Returns the {@link DrawFilter} delegate or null if none have been set.
-     *
-     * @return the delegate or null.
-     */
-    public DrawFilter_Delegate getDrawFilter() {
-        return mDrawFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeCaches() {
-        // nothing to be done here.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeTextLayoutCaches() {
-        // nothing to be done here yet.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitRaster(@Nullable Bitmap bitmap) {
-        long nativeBitmapOrZero = 0;
-        if (bitmap != null) {
-            nativeBitmapOrZero = bitmap.getNativeInstance();
-        }
-        if (nativeBitmapOrZero > 0) {
-            // get the Bitmap from the int
-            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
-
-            // create a new Canvas_Delegate with the given bitmap and return its new native int.
-            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
-
-            return sManager.addNewDelegate(newDelegate);
-        }
-
-        // create a new Canvas_Delegate and return its new native int.
-        Canvas_Delegate newDelegate = new Canvas_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetBitmap(long canvas, Bitmap bitmap) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
-        if (canvasDelegate == null || bitmapDelegate==null) {
-            return;
-        }
-        canvasDelegate.mBitmap = bitmapDelegate;
-        canvasDelegate.mSnapshot = GcSnapshot.createDefaultSnapshot(bitmapDelegate);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nIsOpaque(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetHighContrastText(long nativeCanvas, boolean highContrastText){}
-
-    @LayoutlibDelegate
-    public static int nGetWidth(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getWidth();
-    }
-
-    @LayoutlibDelegate
-    public static int nGetHeight(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.mBitmap.getImage().getHeight();
-    }
-
-    @LayoutlibDelegate
-    public static int nSave(long nativeCanvas, int saveFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.save(saveFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayer(long nativeCanvas, float l,
-                                               float t, float r, float b,
-                                               long paint, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
-        if (paintDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
-                paintDelegate, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static int nSaveLayerAlpha(long nativeCanvas, float l,
-                                                    float t, float r, float b,
-                                                    int alpha, int layerFlags) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nRestore(long nativeCanvas) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        canvasDelegate.restore();
-        return true;
-    }
-
-    @LayoutlibDelegate
-    public static void nRestoreToCount(long nativeCanvas, int saveCount) {
-        // FIXME: implement throwOnUnderflow.
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.restoreTo(saveCount);
-    }
-
-    @LayoutlibDelegate
-    public static int nGetSaveCount(long nativeCanvas) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return 0;
-        }
-
-        return canvasDelegate.getSnapshot().size();
-    }
-
-    @LayoutlibDelegate
-   public static void nTranslate(long nativeCanvas, float dx, float dy) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().translate(dx, dy);
-    }
-
-    @LayoutlibDelegate
-       public static void nScale(long nativeCanvas, float sx, float sy) {
-            // get the delegate from the native int.
-            Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-            if (canvasDelegate == null) {
-                return;
-            }
-
-            canvasDelegate.getSnapshot().scale(sx, sy);
-        }
-
-    @LayoutlibDelegate
-    public static void nRotate(long nativeCanvas, float degrees) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
-    }
-
-    @LayoutlibDelegate
-   public static void nSkew(long nativeCanvas, float kx, float ky) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot g = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = g.getTransform();
-        // get the AffineTransform for the given skew.
-        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
-        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
-
-        // combine them so that the given matrix is applied after.
-        currentTx.preConcatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        g.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nConcat(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get its current matrix
-        AffineTransform currentTx = snapshot.getTransform();
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // combine them so that the given matrix is applied after.
-        currentTx.concatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(currentTx);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetMatrix(long nCanvas, long nMatrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // get the current top graphics2D object.
-        GcSnapshot snapshot = canvasDelegate.getSnapshot();
-
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        snapshot.setTransform(matrixTx);
-
-        if (matrixDelegate.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipRect(long nCanvas,
-                                                  float left, float top,
-                                                  float right, float bottom,
-                                                  int regionOp) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static boolean nClipPath(long nativeCanvas,
-                                                  long nativePath,
-                                                  int regionOp) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return true;
-        }
-
-        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
-        if (pathDelegate == null) {
-            return true;
-        }
-
-        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
-    }
-
-    @LayoutlibDelegate
-    public static void nSetDrawFilter(long nativeCanvas, long nativeFilter) {
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
-
-        if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
-                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
-        }
-    }
-
-    @LayoutlibDelegate
-    public static boolean nGetClipBounds(long nativeCanvas,
-                                                       Rect bounds) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
-        if (canvasDelegate == null) {
-            return false;
-        }
-
-        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
-        if (rect != null && !rect.isEmpty()) {
-            bounds.left = rect.x;
-            bounds.top = rect.y;
-            bounds.right = rect.x + rect.width;
-            bounds.bottom = rect.y + rect.height;
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static void nGetMatrix(long canvas, long matrix) {
-        // get the delegate from the native int.
-        Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-        if (canvasDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
-        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas, long path) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    public static boolean nQuickReject(long nativeCanvas,
-                                                     float left, float top,
-                                                     float right, float bottom) {
-        // FIXME properly implement quickReject
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Canvas_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(nativePtr -> {
-                    Canvas_Delegate delegate = Canvas_Delegate.getDelegate(nativePtr);
-                    if (delegate != null) {
-                        delegate.dispose();
-                    }
-                    sManager.removeJavaReferenceFor(nativePtr);
-                });
-            }
-        }
-        return sFinalizer;
-    }
-
-    private Canvas_Delegate(Bitmap_Delegate bitmap) {
-        super(bitmap);
-    }
-
-    private Canvas_Delegate() {
-        super();
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
deleted file mode 100644
index cb013b6..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Graphics2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorFilter class.
- *
- * This also serve as a base class for all ColorFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class ColorFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<ColorFilter_Delegate> sManager =
-            new DelegateManager<ColorFilter_Delegate>(ColorFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static ColorFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract String getSupportMessage();
-
-    public boolean isSupported() {
-        return false;
-    }
-
-    public void applyFilter(Graphics2D g, int width, int height) {
-        // This should never be called directly. If supported, the sub class should override this.
-        assert false;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nSafeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
deleted file mode 100644
index 6739484..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.ColorMatrixColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of ColorMatrixColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ColorMatrixColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "ColorMatrix Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeColorMatrixFilter(float[] array) {
-        ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
deleted file mode 100644
index bc3df7d..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class ComposePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long outerpe, long innerpe) {
-        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
deleted file mode 100644
index ab37968..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Paint;
-
-/**
- * Delegate implementing the native methods of android.graphics.ComposeShader
- *
- * Through the layoutlib_create tool, the original native methods of ComposeShader have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original ComposeShader class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class ComposeShader_Delegate extends Shader_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Paint getJavaPaint() {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Compose Shaders are not supported in Layout Preview mode.";
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long nativeMatrix, long native_shaderA,
-            long native_shaderB, int native_mode) {
-        // FIXME not supported yet.
-        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate(nativeMatrix);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private ComposeShader_Delegate(long nativeMatrix) {
-        super(nativeMatrix);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
deleted file mode 100644
index 73745c3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.CornerPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original CornerPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class CornerPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Corner Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float radius) {
-        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
deleted file mode 100644
index 881afde..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.BasicStroke;
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
- * {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public final class DashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    private final float[] mIntervals;
-    private final float mPhase;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        return new BasicStroke(
-                paint.getStrokeWidth(),
-                paint.getJavaCap(),
-                paint.getJavaJoin(),
-                paint.getJavaStrokeMiter(),
-                mIntervals,
-                mPhase);
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // no message since isSupported returns true;
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float intervals[], float phase) {
-        DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    private DashPathEffect_Delegate(float intervals[], float phase) {
-        mIntervals = new float[intervals.length];
-        System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
-        mPhase = phase;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
deleted file mode 100644
index 46109f3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.DiscretePathEffect
- *
- * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DiscretePathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Discrete Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(float length, float deviation) {
-        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
deleted file mode 100644
index 2e10740..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.DrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of DrawFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original DrawFilter class.
- *
- * This also serve as a base class for all DrawFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class DrawFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<DrawFilter_Delegate> sManager =
-            new DelegateManager<DrawFilter_Delegate>(DrawFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static DrawFilter_Delegate getDelegate(long nativeDrawFilter) {
-        return sManager.getDelegate(nativeDrawFilter);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long nativeDrawFilter) {
-        sManager.removeJavaReferenceFor(nativeDrawFilter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
deleted file mode 100644
index e5040cc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.EmbossMaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of EmbossMaskFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original EmbossMaskFilter class.
- *
- * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link MaskFilter_Delegate}.
- *
- * @see MaskFilter_Delegate
- *
- */
-public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Emboss Mask Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(float[] direction, float ambient,
-            float specular, float blurRadius) {
-        EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
deleted file mode 100644
index d8e049a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.awt.FontFormatException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
-
-import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
-import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
-
-/**
- * Delegate implementing the native methods of android.graphics.FontFamily
- *
- * Through the layoutlib_create tool, the original native methods of FontFamily have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original FontFamily class.
- *
- * @see DelegateManager
- */
-public class FontFamily_Delegate {
-
-    public static final int DEFAULT_FONT_WEIGHT = 400;
-    public static final int BOLD_FONT_WEIGHT_DELTA = 300;
-    public static final int BOLD_FONT_WEIGHT = 700;
-
-    private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
-    private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt";
-    private static final String EXTENSION_OTF = ".otf";
-
-    private static final int CACHE_SIZE = 10;
-    // The cache has a drawback that if the font file changed after the font object was created,
-    // we will not update it.
-    private static final Map<String, FontInfo> sCache =
-            new LinkedHashMap<String, FontInfo>(CACHE_SIZE) {
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<String, FontInfo> eldest) {
-            return size() > CACHE_SIZE;
-        }
-
-        @Override
-        public FontInfo put(String key, FontInfo value) {
-            // renew this entry.
-            FontInfo removed = remove(key);
-            super.put(key, value);
-            return removed;
-        }
-    };
-
-    /**
-     * A class associating {@link Font} with its metadata.
-     */
-    private static final class FontInfo {
-        @Nullable
-        Font mFont;
-        int mWeight;
-        boolean mIsItalic;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<FontFamily_Delegate> sManager =
-            new DelegateManager<FontFamily_Delegate>(FontFamily_Delegate.class);
-
-    // ---- delegate helper data ----
-    private static String sFontLocation;
-    private static final List<FontFamily_Delegate> sPostInitDelegate = new
-            ArrayList<FontFamily_Delegate>();
-    private static Set<String> SDK_FONTS;
-
-
-    // ---- delegate data ----
-    private List<FontInfo> mFonts = new ArrayList<FontInfo>();
-
-    /**
-     * The variant of the Font Family - compact or elegant.
-     * <p/>
-     * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
-     * android.graphics.FontFamily
-     *
-     * @see Paint#setElegantTextHeight(boolean)
-     */
-    private FontVariant mVariant;
-    // List of runnables to process fonts after sFontLoader is initialized.
-    private List<Runnable> mPostInitRunnables = new ArrayList<Runnable>();
-    /** @see #isValid() */
-    private boolean mValid = false;
-
-
-    // ---- Public helper class ----
-
-    public enum FontVariant {
-        // The order needs to be kept in sync with android.graphics.FontFamily.
-        NONE, COMPACT, ELEGANT
-    }
-
-    // ---- Public Helper methods ----
-
-    public static FontFamily_Delegate getDelegate(long nativeFontFamily) {
-        return sManager.getDelegate(nativeFontFamily);
-    }
-
-    public static synchronized void setFontLocation(String fontLocation) {
-        sFontLocation = fontLocation;
-        // init list of bundled fonts.
-        File allFonts = new File(fontLocation, FN_ALL_FONTS_LIST);
-        // Current number of fonts is 103. Use the next round number to leave scope for more fonts
-        // in the future.
-        Set<String> allFontsList = new HashSet<String>(128);
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(allFonts);
-            while (scanner.hasNext()) {
-                String name = scanner.next();
-                // Skip font configuration files.
-                if (!name.endsWith(".xml")) {
-                    allFontsList.add(name);
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.",
-                    e, null);
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-        SDK_FONTS = Collections.unmodifiableSet(allFontsList);
-        for (FontFamily_Delegate fontFamily : sPostInitDelegate) {
-            fontFamily.init();
-        }
-        sPostInitDelegate.clear();
-    }
-
-    @Nullable
-    public Font getFont(int desiredWeight, boolean isItalic) {
-        FontInfo desiredStyle = new FontInfo();
-        desiredStyle.mWeight = desiredWeight;
-        desiredStyle.mIsItalic = isItalic;
-        FontInfo bestFont = null;
-        int bestMatch = Integer.MAX_VALUE;
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            int match = computeMatch(font, desiredStyle);
-            if (match < bestMatch) {
-                bestMatch = match;
-                bestFont = font;
-            }
-        }
-        if (bestFont == null) {
-            return null;
-        }
-        if (bestMatch == 0) {
-            return bestFont.mFont;
-        }
-        // Derive the font as required and add it to the list of Fonts.
-        deriveFont(bestFont, desiredStyle);
-        addFont(desiredStyle);
-        return desiredStyle.mFont;
-    }
-
-    public FontVariant getVariant() {
-        return mVariant;
-    }
-
-    /**
-     * Returns if the FontFamily should contain any fonts. If this returns true and
-     * {@link #getFont(int, boolean)} returns an empty list, it means that an error occurred while
-     * loading the fonts. However, some fonts are deliberately skipped, for example they are not
-     * bundled with the SDK. In such a case, this method returns false.
-     */
-    public boolean isValid() {
-        return mValid;
-    }
-
-    private static Font loadFont(String path) {
-        if (path.startsWith(SYSTEM_FONTS) ) {
-            String relativePath = path.substring(SYSTEM_FONTS.length());
-            File f = new File(sFontLocation, relativePath);
-
-            try {
-                return Font.createFont(Font.TRUETYPE_FONT, f);
-            } catch (Exception e) {
-                if (path.endsWith(EXTENSION_OTF) && e instanceof FontFormatException) {
-                    // If we aren't able to load an Open Type font, don't log a warning just yet.
-                    // We wait for a case where font is being used. Only then we try to log the
-                    // warning.
-                    return null;
-                }
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unable to load font %1$s", relativePath),
-                        e, null);
-            }
-        } else {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
-                    null, null);
-        }
-
-        return null;
-    }
-
-    @Nullable
-    /*package*/ static String getFontLocation() {
-        return sFontLocation;
-    }
-
-    // ---- delegate methods ----
-    @LayoutlibDelegate
-    /*package*/ static boolean addFont(FontFamily thisFontFamily, String path, int ttcIndex,
-            FontVariationAxis[] axes, int weight, int italic) {
-        if (thisFontFamily.mBuilderPtr == 0) {
-            assert false : "Unable to call addFont after freezing.";
-            return false;
-        }
-        final FontFamily_Delegate delegate = getDelegate(thisFontFamily.mBuilderPtr);
-        return delegate != null && delegate.addFont(path, ttcIndex, weight, italic);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitBuilder(String lang, int variant) {
-        // TODO: support lang. This is required for japanese locale.
-        FontFamily_Delegate delegate = new FontFamily_Delegate();
-        // variant can be 0, 1 or 2.
-        assert variant < 3;
-        delegate.mVariant = FontVariant.values()[variant];
-        if (sFontLocation != null) {
-            delegate.init();
-        } else {
-            sPostInitDelegate.add(delegate);
-        }
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateFamily(long builderPtr) {
-        return builderPtr;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nUnrefFamily(long nativePtr) {
-        // Removing the java reference for the object doesn't mean that it's freed for garbage
-        // collection. Typeface_Delegate may still hold a reference for it.
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
-            int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font,
-            int ttcIndex, int weight, int isItalic) {
-        assert false : "The only client of this method has been overridden.";
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddAxisValue(long builderPtr, int tag, float value) {
-        assert false : "The only client of this method has been overridden.";
-    }
-
-    static boolean addFont(long builderPtr, final String path, final int weight,
-            final boolean isItalic) {
-        final FontFamily_Delegate delegate = getDelegate(builderPtr);
-        int italic = isItalic ? 1 : 0;
-        if (delegate != null) {
-            if (sFontLocation == null) {
-                delegate.mPostInitRunnables.add(() -> delegate.addFont(path, weight, italic));
-                return true;
-            }
-            return delegate.addFont(path, weight, italic);
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
-            int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic) {
-        FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
-        if (ffd == null) {
-            return false;
-        }
-        ffd.mValid = true;
-        if (mgr == null) {
-            return false;
-        }
-        if (mgr instanceof BridgeAssetManager) {
-            InputStream fontStream = null;
-            try {
-                AssetRepository assetRepository = ((BridgeAssetManager) mgr).getAssetRepository();
-                if (assetRepository == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            null);
-                    return false;
-                }
-                if (!assetRepository.isSupported()) {
-                    // Don't log any warnings on unsupported IDEs.
-                    return false;
-                }
-                // Check cache
-                FontInfo fontInfo = sCache.get(path);
-                if (fontInfo != null) {
-                    // renew the font's lease.
-                    sCache.put(path, fontInfo);
-                    ffd.addFont(fontInfo);
-                    return true;
-                }
-                fontStream = isAsset ?
-                        assetRepository.openAsset(path, AssetManager.ACCESS_STREAMING) :
-                        assetRepository.openNonAsset(cookie, path, AssetManager.ACCESS_STREAMING);
-                if (fontStream == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Asset not found: " + path,
-                            path);
-                    return false;
-                }
-                Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
-                fontInfo = new FontInfo();
-                fontInfo.mFont = font;
-                if (weight == RESOLVE_BY_FONT_TABLE) {
-                    fontInfo.mWeight = font.isBold() ? BOLD_FONT_WEIGHT : DEFAULT_FONT_WEIGHT;
-                } else {
-                    fontInfo.mWeight = weight;
-                }
-                fontInfo.mIsItalic = isItalic == RESOLVE_BY_FONT_TABLE ? font.isItalic() :
-                        isItalic == 1;
-                ffd.addFont(fontInfo);
-                return true;
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, "Unable to load font " + path, e,
-                        path);
-            } catch (FontFormatException e) {
-                if (path.endsWith(EXTENSION_OTF)) {
-                    // otf fonts are not supported on the user's config (JRE version + OS)
-                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                            "OpenType fonts are not supported yet: " + path, null, path);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Unable to load font " + path, e, path);
-                }
-            } finally {
-                if (fontStream != null) {
-                    try {
-                        fontStream.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-            return false;
-        }
-        // This should never happen. AssetManager is a final class (from user's perspective), and
-        // we've replaced every creation of AssetManager with our implementation. We create an
-        // exception and log it, but continue with rest of the rendering, without loading this font.
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                "You have found a bug in the rendering library. Please file a bug at b.android.com.",
-                new RuntimeException("Asset Manager is not an instance of BridgeAssetManager"),
-                null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAbort(long builderPtr) {
-        sManager.removeJavaReferenceFor(builderPtr);
-    }
-
-    /**
-     * @see FontFamily#allowUnsupportedFont
-     */
-    @LayoutlibDelegate
-    /*package*/ static void nAllowUnsupportedFont(long builderPtr) {
-        // Do nothing here as this is used for Minikin fonts
-    }
-
-    // ---- private helper methods ----
-
-    private void init() {
-        for (Runnable postInitRunnable : mPostInitRunnables) {
-            postInitRunnable.run();
-        }
-        mPostInitRunnables = null;
-    }
-
-    private boolean addFont(final String path, int ttcIndex, int weight, int italic) {
-        // FIXME: support ttc fonts. Hack JRE??
-        if (sFontLocation == null) {
-            mPostInitRunnables.add(() -> addFont(path, weight, italic));
-            return true;
-        }
-        return addFont(path, weight, italic);
-    }
-
-     private boolean addFont(@NonNull String path) {
-         return addFont(path, DEFAULT_FONT_WEIGHT, path.endsWith(FONT_SUFFIX_ITALIC) ? 1 : RESOLVE_BY_FONT_TABLE);
-     }
-
-    private boolean addFont(@NonNull String path, int weight, int italic) {
-        if (path.startsWith(SYSTEM_FONTS) &&
-                !SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
-            return mValid = false;
-        }
-        // Set valid to true, even if the font fails to load.
-        mValid = true;
-        Font font = loadFont(path);
-        if (font == null) {
-            return false;
-        }
-        FontInfo fontInfo = new FontInfo();
-        fontInfo.mFont = font;
-        fontInfo.mWeight = weight;
-        fontInfo.mIsItalic = italic == RESOLVE_BY_FONT_TABLE ? font.isItalic() : italic == 1;
-        addFont(fontInfo);
-        return true;
-    }
-
-    private boolean addFont(@NonNull FontInfo fontInfo) {
-        int weight = fontInfo.mWeight;
-        boolean isItalic = fontInfo.mIsItalic;
-        // The list is usually just two fonts big. So iterating over all isn't as bad as it looks.
-        // It's biggest for roboto where the size is 12.
-        //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-        for (int i = 0, n = mFonts.size(); i < n; i++) {
-            FontInfo font = mFonts.get(i);
-            if (font.mWeight == weight && font.mIsItalic == isItalic) {
-                return false;
-            }
-        }
-        mFonts.add(fontInfo);
-        return true;
-    }
-
-    /**
-     * Compute matching metric between two styles - 0 is an exact match.
-     */
-    private static int computeMatch(@NonNull FontInfo font1, @NonNull FontInfo font2) {
-        int score = Math.abs(font1.mWeight - font2.mWeight);
-        if (font1.mIsItalic != font2.mIsItalic) {
-            score += 200;
-        }
-        return score;
-    }
-
-    /**
-     * Try to derive a font from {@code srcFont} for the style in {@code outFont}.
-     * <p/>
-     * {@code outFont} is updated to reflect the style of the derived font.
-     * @param srcFont the source font
-     * @param outFont contains the desired font style. Updated to contain the derived font and
-     *                its style
-     * @return outFont
-     */
-    @NonNull
-    private FontInfo deriveFont(@NonNull FontInfo srcFont, @NonNull FontInfo outFont) {
-        int desiredWeight = outFont.mWeight;
-        int srcWeight = srcFont.mWeight;
-        assert srcFont.mFont != null;
-        Font derivedFont = srcFont.mFont;
-        // Embolden the font if required.
-        if (desiredWeight >= BOLD_FONT_WEIGHT && desiredWeight - srcWeight > BOLD_FONT_WEIGHT_DELTA / 2) {
-            derivedFont = derivedFont.deriveFont(Font.BOLD);
-            srcWeight += BOLD_FONT_WEIGHT_DELTA;
-        }
-        // Italicize the font if required.
-        if (outFont.mIsItalic && !srcFont.mIsItalic) {
-            derivedFont = derivedFont.deriveFont(Font.ITALIC);
-        } else if (outFont.mIsItalic != srcFont.mIsItalic) {
-            // The desired font is plain, but the src font is italics. We can't convert it back. So
-            // we update the value to reflect the true style of the font we're deriving.
-            outFont.mIsItalic = srcFont.mIsItalic;
-        }
-        outFont.mFont = derivedFont;
-        outFont.mWeight = srcWeight;
-        // No need to update mIsItalics, as it's already been handled above.
-        return outFont;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
deleted file mode 100644
index 64410e4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Base class for true Gradient shader delegate.
- */
-public abstract class Gradient_Delegate extends Shader_Delegate {
-
-    protected final int[] mColors;
-    protected final float[] mPositions;
-
-    @Override
-    public boolean isSupported() {
-        // all gradient shaders are supported.
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        // all gradient shaders are supported, no need for a gradient support
-        return null;
-    }
-
-    /**
-     * Creates the base shader and do some basic test on the parameters.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     */
-    protected Gradient_Delegate(long nativeMatrix, int colors[], float positions[]) {
-        super(nativeMatrix);
-        assert colors.length >= 2 : "needs >= 2 number of colors";
-
-        if (positions == null) {
-            float spacing = 1.f / (colors.length - 1);
-            positions = new float[colors.length];
-            positions[0] = 0.f;
-            positions[colors.length - 1] = 1.f;
-            for (int i = 1; i < colors.length - 1; i++) {
-                positions[i] = spacing * i;
-            }
-        } else {
-            assert colors.length == positions.length :
-                    "color and position " + "arrays must be of equal length";
-        }
-
-        mColors = colors;
-        mPositions = positions;
-    }
-
-    /**
-     * Base class for (Java) Gradient Paints. This handles computing the gradient colors based
-     * on the color and position lists, as well as the {@link TileMode}
-     *
-     */
-    protected abstract static class GradientPaint implements java.awt.Paint {
-        private final static int GRADIENT_SIZE = 100;
-
-        private final int[] mColors;
-        private final float[] mPositions;
-        private final TileMode mTileMode;
-        private int[] mGradient;
-
-        protected GradientPaint(int[] colors, float[] positions, TileMode tileMode) {
-            mColors = colors;
-            mPositions = positions;
-            mTileMode = tileMode;
-        }
-
-        @Override
-        public int getTransparency() {
-            return java.awt.Paint.TRANSLUCENT;
-        }
-
-        /**
-         * Pre-computes the colors for the gradient. This must be called once before any call
-         * to {@link #getGradientColor(float)}
-         */
-        protected void precomputeGradientColors() {
-            if (mGradient == null) {
-                // actually create an array with an extra size, so that we can really go
-                // from 0 to SIZE (100%), or currentPos in the loop below will never equal 1.0
-                mGradient = new int[GRADIENT_SIZE+1];
-
-                int prevPos = 0;
-                int nextPos = 1;
-                for (int i  = 0 ; i <= GRADIENT_SIZE ; i++) {
-                    // compute current position
-                    float currentPos = (float)i/GRADIENT_SIZE;
-                    while (currentPos > mPositions[nextPos]) {
-                        prevPos = nextPos++;
-                    }
-
-                    float percent = (currentPos - mPositions[prevPos]) /
-                            (mPositions[nextPos] - mPositions[prevPos]);
-
-                    mGradient[i] = computeColor(mColors[prevPos], mColors[nextPos], percent);
-                }
-            }
-        }
-
-        /**
-         * Returns the color based on the position in the gradient.
-         * <var>pos</var> can be anything, even &lt; 0 or &gt; > 1, as the gradient
-         * will use {@link TileMode} value to convert it into a [0,1] value.
-         */
-        protected int getGradientColor(float pos) {
-            if (pos < 0.f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 0.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range.
-                            // we also need to invert the value from [-1,0] to [0, 1]
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // this is the same as the positive side, just make the value positive
-                            // first.
-                            pos = Math.abs(pos);
-
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 0.0f;
-                }
-            } else if (pos > 1f) {
-                if (mTileMode != null) {
-                    switch (mTileMode) {
-                        case CLAMP:
-                            pos = 1.f;
-                            break;
-                        case REPEAT:
-                            // remove the integer part to stay in the [0,1] range
-                            pos = pos - (float)Math.floor(pos);
-                            break;
-                        case MIRROR:
-                            // get the integer and the decimal part
-                            int intPart = (int)Math.floor(pos);
-                            pos = pos - intPart;
-                            // 0 -> 1 : normal order
-                            // 1 -> 2: mirrored
-                            // etc..
-                            // this means if the intpart is odd we invert
-                            if ((intPart % 2) == 1) {
-                                pos = 1.f - pos;
-                            }
-                            break;
-                    }
-                } else {
-                    pos = 1.0f;
-                }
-            }
-
-            int index = (int)((pos * GRADIENT_SIZE) + .5);
-
-            return mGradient[index];
-        }
-
-        /**
-         * Returns the color between c1, and c2, based on the percent of the distance
-         * between c1 and c2.
-         */
-        private int computeColor(int c1, int c2, float percent) {
-            int a = computeChannel((c1 >> 24) & 0xFF, (c2 >> 24) & 0xFF, percent);
-            int r = computeChannel((c1 >> 16) & 0xFF, (c2 >> 16) & 0xFF, percent);
-            int g = computeChannel((c1 >>  8) & 0xFF, (c2 >>  8) & 0xFF, percent);
-            int b = computeChannel((c1      ) & 0xFF, (c2      ) & 0xFF, percent);
-            return a << 24 | r << 16 | g << 8 | b;
-        }
-
-        /**
-         * Returns the channel value between 2 values based on the percent of the distance between
-         * the 2 values..
-         */
-        private int computeChannel(int c1, int c2, float percent) {
-            return c1 + (int)((percent * (c2-c1)) + .5);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
deleted file mode 100644
index 0dd9703..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.LightingColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of LightingColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LightingColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public String getSupportMessage() {
-        return "Lighting Color Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreateLightingFilter(int mul, int add) {
-        LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
deleted file mode 100644
index cd4393a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.LinearGradient
- *
- * Through the layoutlib_create tool, the original native methods of LinearGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original LinearGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public final class LinearGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int colors[], float positions[], int tileMode) {
-        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(matrix, x0, y0,
-                x1, y1, colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(LinearGradient thisGradient, long matrix,
-            float x0, float y0, float x1, float y1,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(thisGradient, matrix, x0, y0, x1, y1, new int[] { color0, color1},
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    private LinearGradient_Delegate(long nativeMatrix, float x0, float y0, float x1,
-            float y1, int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
-    }
-
-    // ---- Custom Java Paint ----
-    /**
-     * Linear Gradient (Java) Paint able to handle more than 2 points, as
-     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
-     * modes.
-     */
-    private class LinearGradientPaint extends GradientPaint {
-
-        private final float mX0;
-        private final float mY0;
-        private final float mDx;
-        private final float mDy;
-        private final float mDSize2;
-
-        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
-                float positions[], TileMode tile) {
-            super(colors, positions, tile);
-            mX0 = x0;
-            mY0 = y0;
-            mDx = x1 - x0;
-            mDy = y1 - y0;
-            mDSize2 = mDx * mDx + mDy * mDy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class LinearGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            private LinearGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix.
-                        pt1[0] = pt2[0];
-                        pt1[1] = pt2[1];
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        data[index++] = getColor(pt2[0], pt2[1]);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float x, float y) {
-            float pos;
-            if (mDx == 0) {
-                pos = (y - mY0) / mDy;
-            } else if (mDy == 0) {
-                pos = (x - mX0) / mDx;
-            } else {
-                // find the x position on the gradient vector.
-                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-                // from it get the position relative to the vector
-                pos = (_x - mX0) / mDx;
-            }
-
-            return getGradientColor(pos);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
deleted file mode 100644
index e726c59..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.MaskFilter
- *
- * Through the layoutlib_create tool, the original native methods of MaskFilter have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original MaskFilter class.
- *
- * This also serve as a base class for all MaskFilter delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class MaskFilter_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<MaskFilter_Delegate> sManager =
-            new DelegateManager<MaskFilter_Delegate>(MaskFilter_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static MaskFilter_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_filter) {
-        sManager.removeJavaReferenceFor(native_filter);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
deleted file mode 100644
index 354f919..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix.ScaleToFit;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Matrix
- *
- * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Matrix class.
- *
- * @see DelegateManager
- *
- */
-public final class Matrix_Delegate {
-
-    private final static int MATRIX_SIZE = 9;
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Matrix_Delegate> sManager =
-            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate data ----
-    private float mValues[] = new float[MATRIX_SIZE];
-
-    // ---- Public Helper methods ----
-
-    public static Matrix_Delegate getDelegate(long native_instance) {
-        return sManager.getDelegate(native_instance);
-    }
-
-    /**
-     * Returns an {@link AffineTransform} matching the given Matrix.
-     */
-    public static AffineTransform getAffineTransform(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return null;
-        }
-
-        return delegate.getAffineTransform();
-    }
-
-    public static boolean hasPerspective(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
-        if (delegate == null) {
-            return false;
-        }
-
-        return delegate.hasPerspective();
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix.
-     */
-    public void set(Matrix_Delegate matrix) {
-        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Sets the content of the matrix with the content of another matrix represented as an array
-     * of values.
-     */
-    public void set(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Resets the matrix to be the identity matrix.
-     */
-    public void reset() {
-        reset(mValues);
-    }
-
-    /**
-     * Returns whether or not the matrix is identity.
-     */
-    public boolean isIdentity() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                if (mValues[k] != ((i==j) ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public static float[] makeValues(AffineTransform matrix) {
-        float[] values = new float[MATRIX_SIZE];
-        values[0] = (float) matrix.getScaleX();
-        values[1] = (float) matrix.getShearX();
-        values[2] = (float) matrix.getTranslateX();
-        values[3] = (float) matrix.getShearY();
-        values[4] = (float) matrix.getScaleY();
-        values[5] = (float) matrix.getTranslateY();
-        values[6] = 0.f;
-        values[7] = 0.f;
-        values[8] = 1.f;
-
-        return values;
-    }
-
-    public static Matrix_Delegate make(AffineTransform matrix) {
-        return new Matrix_Delegate(makeValues(matrix));
-    }
-
-    public boolean mapRect(RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        mapPoints(corners);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-
-
-        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-
-    /**
-     * Returns an {@link AffineTransform} matching the matrix.
-     */
-    public AffineTransform getAffineTransform() {
-        return getAffineTransform(mValues);
-    }
-
-    public boolean hasPerspective() {
-        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
-    }
-
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(long native_src_or_zero) {
-        // create the delegate
-        Matrix_Delegate newDelegate = new Matrix_Delegate();
-
-        // copy from values if needed.
-        if (native_src_or_zero > 0) {
-            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
-            if (oldDelegate != null) {
-                System.arraycopy(
-                        oldDelegate.mValues, 0,
-                        newDelegate.mValues, 0,
-                        MATRIX_SIZE);
-            }
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsIdentity(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.isIdentity();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsAffine(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kPerspective_Mask) == 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nRectStaysRect(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return true;
-        }
-
-        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        reset(d.mValues);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_object, long other) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        Matrix_Delegate src = sManager.getDelegate(other);
-        if (src == null) {
-            return;
-        }
-
-        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setTranslate(d.mValues, dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getScale(sx, sy, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = sx;
-        d.mValues[1] = 0;
-        d.mValues[2] = 0;
-        d.mValues[3] = 0;
-        d.mValues[4] = sy;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees, float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getRotate(degrees, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, degrees);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(d.mValues, -px, -py);
-
-        // scale
-        d.postTransform(getRotate(sinValue, cosValue));
-        // translate back the pivot
-        d.postTransform(getTranslate(px, py));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        setRotate(d.mValues, sinValue, cosValue);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues = getSkew(kx, ky, px, py);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        d.mValues[0] = 1;
-        d.mValues[1] = kx;
-        d.mValues[2] = -0;
-        d.mValues[3] = ky;
-        d.mValues[4] = 1;
-        d.mValues[5] = 0;
-        d.mValues[6] = 0;
-        d.mValues[7] = 0;
-        d.mValues[8] = 1;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetConcat(long native_object, long a, long b) {
-        if (a == native_object) {
-            nPreConcat(native_object, b);
-            return;
-        } else if (b == native_object) {
-            nPostConcat(native_object, a);
-            return;
-        }
-
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate a_mtx = sManager.getDelegate(a);
-        Matrix_Delegate b_mtx = sManager.getDelegate(b);
-        if (d != null && a_mtx != null && b_mtx != null) {
-            multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-
-            double rad = Math.toRadians(degrees);
-            float sin = (float) Math.sin(rad);
-            float cos = (float) Math.cos(rad);
-
-            d.preTransform(getRotate(sin, cos));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.preTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPreConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.preTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostTranslate(long native_object, float dx, float dy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getTranslate(dx, dy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostScale(long native_object, float sx, float sy) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getScale(sx, sy));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostRotate(long native_object, float degrees) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getRotate(degrees));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky,
-            float px, float py) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky, px, py));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostSkew(long native_object, float kx, float ky) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d != null) {
-            d.postTransform(getSkew(kx, ky));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nPostConcat(long native_object, long other_matrix) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        Matrix_Delegate other = sManager.getDelegate(other_matrix);
-        if (d != null && other != null) {
-            d.postTransform(other.mValues);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRectToRect(long native_object, RectF src,
-            RectF dst, int stf) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        if (src.isEmpty()) {
-            reset(d.mValues);
-            return false;
-        }
-
-        if (dst.isEmpty()) {
-            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
-               = d.mValues[6] = d.mValues[7] = 0;
-            d.mValues[8] = 1;
-        } else {
-            float    tx, sx = dst.width() / src.width();
-            float    ty, sy = dst.height() / src.height();
-            boolean  xLarger = false;
-
-            if (stf != ScaleToFit.FILL.nativeInt) {
-                if (sx > sy) {
-                    xLarger = true;
-                    sx = sy;
-                } else {
-                    sy = sx;
-                }
-            }
-
-            tx = dst.left - src.left * sx;
-            ty = dst.top - src.top * sy;
-            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
-                float diff;
-
-                if (xLarger) {
-                    diff = dst.width() - src.width() * sy;
-                } else {
-                    diff = dst.height() - src.height() * sy;
-                }
-
-                if (stf == ScaleToFit.CENTER.nativeInt) {
-                    diff = diff / 2;
-                }
-
-                if (xLarger) {
-                    tx += diff;
-                } else {
-                    ty += diff;
-                }
-            }
-
-            d.mValues[0] = sx;
-            d.mValues[4] = sy;
-            d.mValues[2] = tx;
-            d.mValues[5] = ty;
-            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;
-
-        }
-        // shared cleanup
-        d.mValues[8] = 1;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex,
-            float[] dst, int dstIndex, int pointCount) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Matrix.setPolyToPoly is not supported.",
-                null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInvert(long native_object, long inverse) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
-        if (inv_mtx == null) {
-            return false;
-        }
-
-        try {
-            AffineTransform affineTransform = d.getAffineTransform();
-            AffineTransform inverseTransform = affineTransform.createInverse();
-            inv_mtx.mValues[0] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[1] = (float)inverseTransform.getShearX();
-            inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX();
-            inv_mtx.mValues[3] = (float)inverseTransform.getScaleX();
-            inv_mtx.mValues[4] = (float)inverseTransform.getShearY();
-            inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY();
-
-            return true;
-        } catch (NoninvertibleTransformException e) {
-            return false;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMapPoints(long native_object, float[] dst, int dstIndex,
-            float[] src, int srcIndex, int ptCount, boolean isPts) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        if (isPts) {
-            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-        } else {
-            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nMapRect(long native_object, RectF dst, RectF src) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return false;
-        }
-
-        return d.mapRect(dst, src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nMapRadius(long native_object, float radius) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return 0.f;
-        }
-
-        float[] src = new float[] { radius, 0.f, 0.f, radius };
-        d.mapVectors(src, 0, src, 0, 2);
-
-        float l1 = (float) Math.hypot(src[0], src[1]);
-        float l2 = (float) Math.hypot(src[2], src[3]);
-        return (float) Math.sqrt(l1 * l2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetValues(long native_object, float[] values) {
-        Matrix_Delegate d = sManager.getDelegate(native_object);
-        if (d == null) {
-            return;
-        }
-
-        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nEquals(long native_a, long native_b) {
-        Matrix_Delegate a = sManager.getDelegate(native_a);
-        if (a == null) {
-            return false;
-        }
-
-        Matrix_Delegate b = sManager.getDelegate(native_b);
-        if (b == null) {
-            return false;
-        }
-
-        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
-            if (a.mValues[i] != b.mValues[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Matrix_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    // ---- Private helper methods ----
-
-    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
-        // the AffineTransform constructor takes the value in a different order
-        // for a matrix [ 0 1 2 ]
-        //              [ 3 4 5 ]
-        // the order is 0, 3, 1, 4, 2, 5...
-        return new AffineTransform(
-                matrix[0], matrix[3], matrix[1],
-                matrix[4], matrix[2], matrix[5]);
-    }
-
-    /**
-     * Reset a matrix to the identity
-     */
-    private static void reset(float[] mtx) {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                mtx[k] = ((i==j) ? 1 : 0);
-            }
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private final static int kIdentity_Mask      = 0;
-    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
-    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
-    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
-    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
-    private final static int kRectStaysRect_Mask = 0x10;
-    @SuppressWarnings("unused")
-    private final static int kUnknown_Mask       = 0x80;
-
-    @SuppressWarnings("unused")
-    private final static int kAllMasks           = kTranslate_Mask |
-                                                   kScale_Mask |
-                                                   kAffine_Mask |
-                                                   kPerspective_Mask |
-                                                   kRectStaysRect_Mask;
-
-    // these guys align with the masks, so we can compute a mask from a variable 0/1
-    @SuppressWarnings("unused")
-    private final static int kTranslate_Shift = 0;
-    @SuppressWarnings("unused")
-    private final static int kScale_Shift = 1;
-    @SuppressWarnings("unused")
-    private final static int kAffine_Shift = 2;
-    @SuppressWarnings("unused")
-    private final static int kPerspective_Shift = 3;
-    private final static int kRectStaysRect_Shift = 4;
-
-    private int computeTypeMask() {
-        int mask = 0;
-
-        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
-            mask |= kPerspective_Mask;
-        }
-
-        if (mValues[2] != 0. || mValues[5] != 0.) {
-            mask |= kTranslate_Mask;
-        }
-
-        float m00 = mValues[0];
-        float m01 = mValues[1];
-        float m10 = mValues[3];
-        float m11 = mValues[4];
-
-        if (m01 != 0. || m10 != 0.) {
-            mask |= kAffine_Mask;
-        }
-
-        if (m00 != 1. || m11 != 1.) {
-            mask |= kScale_Mask;
-        }
-
-        if ((mask & kPerspective_Mask) == 0) {
-            // map non-zero to 1
-            int im00 = m00 != 0 ? 1 : 0;
-            int im01 = m01 != 0 ? 1 : 0;
-            int im10 = m10 != 0 ? 1 : 0;
-            int im11 = m11 != 0 ? 1 : 0;
-
-            // record if the (p)rimary and (s)econdary diagonals are all 0 or
-            // all non-zero (answer is 0 or 1)
-            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
-            int dp1 = im00 & im11;        // true if both are 1
-            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
-            int ds1 = im01 & im10;        // true if both are 1
-
-            // return 1 if primary is 1 and secondary is 0 or
-            // primary is 0 and secondary is 1
-            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
-        }
-
-        return mask;
-    }
-
-    private Matrix_Delegate() {
-        reset();
-    }
-
-    private Matrix_Delegate(float[] values) {
-        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = this*matrix
-     * @param matrix
-     */
-    private void postTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, mValues, matrix);
-        mValues = tmp;
-    }
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = matrix*this
-     * @param matrix
-     */
-    private void preTransform(float[] matrix) {
-        float[] tmp = new float[9];
-        multiply(tmp, matrix, mValues);
-        mValues = tmp;
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points specified by src, and write
-      * the transformed points into the array of points specified by dst. The
-      * two arrays represent their "points" as pairs of floats [x, y].
-      *
-      * @param dst   The array of dst points (x,y pairs)
-      * @param dstIndex The index of the first [x,y] pair of dst floats
-      * @param src   The array of src points (x,y pairs)
-      * @param srcIndex The index of the first [x,y] pair of src floats
-      * @param pointCount The number of points (x,y pairs) to transform
-      */
-
-     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
-                           int pointCount) {
-         final int count = pointCount * 2;
-
-         float[] tmpDest = dst;
-         boolean inPlace = dst == src;
-         if (inPlace) {
-             tmpDest = new float[dstIndex + count];
-         }
-
-         for (int i = 0 ; i < count ; i += 2) {
-             // just in case we are doing in place, we better put this in temp vars
-             float x = mValues[0] * src[i + srcIndex] +
-                       mValues[1] * src[i + srcIndex + 1] +
-                       mValues[2];
-             float y = mValues[3] * src[i + srcIndex] +
-                       mValues[4] * src[i + srcIndex + 1] +
-                       mValues[5];
-
-             tmpDest[i + dstIndex]     = x;
-             tmpDest[i + dstIndex + 1] = y;
-         }
-
-         if (inPlace) {
-             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
-         }
-     }
-
-     /**
-      * Apply this matrix to the array of 2D points, and write the transformed
-      * points back into the array
-      *
-      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
-      */
-
-     private void mapPoints(float[] pts) {
-         mapPoints(pts, 0, pts, 0, pts.length >> 1);
-     }
-
-     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
-         if (hasPerspective()) {
-             // transform the (0,0) point
-             float[] origin = new float[] { 0.f, 0.f};
-             mapPoints(origin);
-
-             // translate the vector data as points
-             mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-
-             // then substract the transformed origin.
-             final int count = ptCount * 2;
-             for (int i = 0 ; i < count ; i += 2) {
-                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
-                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
-             }
-         } else {
-             // make a copy of the matrix
-             Matrix_Delegate copy = new Matrix_Delegate(mValues);
-
-             // remove the translation
-             setTranslate(copy.mValues, 0, 0);
-
-             // map the content as points.
-             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
-         }
-     }
-
-    /**
-     * multiply two matrices and store them in a 3rd.
-     * <p/>This in effect does dest = a*b
-     * dest cannot be the same as a or b.
-     */
-     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
-        // first row
-        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
-        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
-        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];
-
-        // 2nd row
-        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
-        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
-        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];
-
-        // 3rd row
-        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
-        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
-        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
-    }
-
-    /**
-     * Returns a matrix that represents a given translate
-     * @param dx
-     * @param dy
-     * @return
-     */
-    /*package*/ static float[] getTranslate(float dx, float dy) {
-        return setTranslate(new float[9], dx, dy);
-    }
-
-    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
-        dest[0] = 1;
-        dest[1] = 0;
-        dest[2] = dx;
-        dest[3] = 0;
-        dest[4] = 1;
-        dest[5] = dy;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getScale(float sx, float sy) {
-        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
-    }
-
-    /**
-     * Returns a matrix that represents the given scale info.
-     * @param sx
-     * @param sy
-     * @param px
-     * @param py
-     */
-    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate tmp so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // scale into tmp2
-        multiply(tmp2, tmp, getScale(sx, sy));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-
-    /*package*/ static float[] getRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return getRotate(sin, cos);
-    }
-
-    /*package*/ static float[] getRotate(float sin, float cos) {
-        return setRotate(new float[9], sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float degrees) {
-        double rad = Math.toRadians(degrees);
-        float sin = (float)Math.sin(rad);
-        float cos = (float)Math.cos(rad);
-
-        return setRotate(dest, sin, cos);
-    }
-
-    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
-        dest[0] = cos;
-        dest[1] = -sin;
-        dest[2] = 0;
-        dest[3] = sin;
-        dest[4] = cos;
-        dest[5] = 0;
-        dest[6] = 0;
-        dest[7] = 0;
-        dest[8] = 1;
-        return dest;
-    }
-
-    /*package*/ static float[] getRotate(float degrees, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // rotate into tmp2
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        multiply(tmp2, tmp, getRotate(sin, cos));
-
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky) {
-        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
-    }
-
-    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
-        float[] tmp = new float[9];
-        float[] tmp2 = new float[9];
-
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        setTranslate(tmp, -px, -py);
-
-        // skew into tmp2
-        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot back into tmp
-        multiply(tmp, tmp2, getTranslate(px, py));
-
-        return tmp;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
deleted file mode 100644
index 1f0eb3b..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.GcSnapshot;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.drawable.NinePatchDrawable;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.graphics.NinePatch
- *
- * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public final class NinePatch_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NinePatch_Delegate> sManager =
-            new DelegateManager<NinePatch_Delegate>(NinePatch_Delegate.class);
-
-    // ---- delegate helper data ----
-    /**
-     * Cache map for {@link NinePatchChunk}.
-     * When the chunks are created they are serialized into a byte[], and both are put
-     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
-     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
-     * provide this for drawing.
-     * Using the cache map allows us to not have to deserialize the byte[] back into a
-     * {@link NinePatchChunk} every time a rendering is done.
-     */
-    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
-        new HashMap<byte[], SoftReference<NinePatchChunk>>();
-
-    // ---- delegate data ----
-    private byte[] chunk;
-
-
-    // ---- Public Helper methods ----
-
-    /**
-     * Serializes the given chunk.
-     *
-     * @return the serialized data for the chunk.
-     */
-    public static byte[] serialize(NinePatchChunk chunk) {
-        // serialize the chunk to get a byte[]
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = null;
-        try {
-            oos = new ObjectOutputStream(baos);
-            oos.writeObject(chunk);
-        } catch (IOException e) {
-            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
-            return null;
-        } finally {
-            if (oos != null) {
-                try {
-                    oos.close();
-                } catch (IOException ignored) {
-                }
-            }
-        }
-
-        // get the array and add it to the cache
-        byte[] array = baos.toByteArray();
-        sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-        return array;
-    }
-
-    /**
-     * Returns a {@link NinePatchChunk} object for the given serialized representation.
-     *
-     * If the chunk is present in the cache then the object from the cache is returned, otherwise
-     * the array is deserialized into a {@link NinePatchChunk} object.
-     *
-     * @param array the serialized representation of the chunk.
-     * @return the NinePatchChunk or null if deserialization failed.
-     */
-    public static NinePatchChunk getChunk(byte[] array) {
-        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
-        NinePatchChunk chunk = chunkRef.get();
-        if (chunk == null) {
-            ByteArrayInputStream bais = new ByteArrayInputStream(array);
-            ObjectInputStream ois = null;
-            try {
-                ois = new ObjectInputStream(bais);
-                chunk = (NinePatchChunk) ois.readObject();
-
-                // put back the chunk in the cache
-                if (chunk != null) {
-                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-                }
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
-                return null;
-            } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
-                return null;
-            } finally {
-                if (ois != null) {
-                    try {
-                        ois.close();
-                    } catch (IOException ignored) {
-                    }
-                }
-            }
-        }
-
-        return chunk;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
-        NinePatchChunk chunkObject = getChunk(chunk);
-        return chunkObject != null;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long validateNinePatchChunk(byte[] chunk) {
-        // the default JNI implementation only checks that the byte[] has the same
-        // size as the C struct it represent. Since we cannot do the same check (serialization
-        // will return different size depending on content), we do nothing.
-        NinePatch_Delegate newDelegate = new NinePatch_Delegate();
-        newDelegate.chunk = chunk;
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeFinalize(long chunk) {
-        sManager.removeJavaReferenceFor(chunk);
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) {
-        return 0;
-    }
-
-    static byte[] getChunk(long nativeNinePatch) {
-        NinePatch_Delegate delegate = sManager.getDelegate(nativeNinePatch);
-        if (delegate != null) {
-            return delegate.chunk;
-        }
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
deleted file mode 100644
index fa20746..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.PaintFlagsDrawFilter
- *
- * Through the layoutlib_create tool, the original native methods of PaintFlagsDrawFilter have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PaintFlagsDrawFilter class.
- *
- * Because this extends {@link DrawFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the DrawFilter classes will be added to the manager owned by
- * {@link DrawFilter_Delegate}.
- *
- * @see DrawFilter_Delegate
- *
- */
-public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Paint Flags Draw Filters are not supported.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor(int clearBits, int setBits) {
-        PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
deleted file mode 100644
index 1bb56e3..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.Paint.FontMetrics;
-import android.graphics.Paint.FontMetricsInt;
-import android.text.TextUtils;
-
-import java.awt.BasicStroke;
-import java.awt.Font;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.Paint
- *
- * Through the layoutlib_create tool, the original native methods of Paint have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Paint class.
- *
- * @see DelegateManager
- *
- */
-public class Paint_Delegate {
-
-    /**
-     * Class associating a {@link Font} and its {@link java.awt.FontMetrics}.
-     */
-    /*package*/ static final class FontInfo {
-        Font mFont;
-        java.awt.FontMetrics mMetrics;
-    }
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Paint_Delegate> sManager =
-            new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
-    private static long sFinalizer = -1;
-
-    // ---- delegate helper data ----
-
-    // This list can contain null elements.
-    private List<FontInfo> mFonts;
-
-    // ---- delegate data ----
-    private int mFlags;
-    private int mColor;
-    private int mStyle;
-    private int mCap;
-    private int mJoin;
-    private int mTextAlign;
-    private Typeface_Delegate mTypeface;
-    private float mStrokeWidth;
-    private float mStrokeMiter;
-    private float mTextSize;
-    private float mTextScaleX;
-    private float mTextSkewX;
-    private int mHintingMode = Paint.HINTING_ON;
-    private int mHyphenEdit;
-    private float mLetterSpacing;  // not used in actual text rendering.
-    private float mWordSpacing;  // not used in actual text rendering.
-    // Variant of the font. A paint's variant can only be compact or elegant.
-    private FontVariant mFontVariant = FontVariant.COMPACT;
-
-    private int mPorterDuffMode = Xfermode.DEFAULT;
-    private ColorFilter_Delegate mColorFilter;
-    private Shader_Delegate mShader;
-    private PathEffect_Delegate mPathEffect;
-    private MaskFilter_Delegate mMaskFilter;
-
-    private Locale mLocale = Locale.getDefault();
-
-    // Used only to assert invariants.
-    public long mNativeTypeface;
-
-    // ---- Public Helper methods ----
-
-    @Nullable
-    public static Paint_Delegate getDelegate(long native_paint) {
-        return sManager.getDelegate(native_paint);
-    }
-
-    /**
-     * Returns the list of {@link Font} objects.
-     */
-    public List<FontInfo> getFonts() {
-        return mFonts;
-    }
-
-    public boolean isAntiAliased() {
-        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
-    }
-
-    public boolean isFilterBitmap() {
-        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
-    }
-
-    public int getStyle() {
-        return mStyle;
-    }
-
-    public int getColor() {
-        return mColor;
-    }
-
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
-    public void setAlpha(int alpha) {
-        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
-    }
-
-    public int getTextAlign() {
-        return mTextAlign;
-    }
-
-    public float getStrokeWidth() {
-        return mStrokeWidth;
-    }
-
-    /**
-     * returns the value of stroke miter needed by the java api.
-     */
-    public float getJavaStrokeMiter() {
-        return mStrokeMiter;
-    }
-
-    public int getJavaCap() {
-        switch (Paint.sCapArray[mCap]) {
-            case BUTT:
-                return BasicStroke.CAP_BUTT;
-            case ROUND:
-                return BasicStroke.CAP_ROUND;
-            default:
-            case SQUARE:
-                return BasicStroke.CAP_SQUARE;
-        }
-    }
-
-    public int getJavaJoin() {
-        switch (Paint.sJoinArray[mJoin]) {
-            default:
-            case MITER:
-                return BasicStroke.JOIN_MITER;
-            case ROUND:
-                return BasicStroke.JOIN_ROUND;
-            case BEVEL:
-                return BasicStroke.JOIN_BEVEL;
-        }
-    }
-
-    public Stroke getJavaStroke() {
-        if (mPathEffect != null) {
-            if (mPathEffect.isSupported()) {
-                Stroke stroke = mPathEffect.getStroke(this);
-                assert stroke != null;
-                if (stroke != null) {
-                    return stroke;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
-                        mPathEffect.getSupportMessage(),
-                        null, null /*data*/);
-            }
-        }
-
-        // if no custom stroke as been set, set the default one.
-        return new BasicStroke(
-                    getStrokeWidth(),
-                    getJavaCap(),
-                    getJavaJoin(),
-                    getJavaStrokeMiter());
-    }
-
-    /**
-     * Returns the {@link PorterDuff.Mode} as an int
-     */
-    public int getPorterDuffMode() {
-        return mPorterDuffMode;
-    }
-
-    /**
-     * Returns the {@link ColorFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public ColorFilter_Delegate getColorFilter() {
-        return mColorFilter;
-    }
-
-    public void setColorFilter(long colorFilterPtr) {
-        mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
-    }
-
-    public void setShader(long shaderPtr) {
-        mShader = Shader_Delegate.getDelegate(shaderPtr);
-    }
-
-    /**
-     * Returns the {@link Shader} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public Shader_Delegate getShader() {
-        return mShader;
-    }
-
-    /**
-     * Returns the {@link MaskFilter} delegate or null if none have been set
-     *
-     * @return the delegate or null.
-     */
-    public MaskFilter_Delegate getMaskFilter() {
-        return mMaskFilter;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFlags(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mFlags;
-    }
-
-
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFlags(long nativePaint, int flags) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFlags = flags;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFilterBitmap(long nativePaint, boolean filter) {
-        setFlag(nativePaint, Paint.FILTER_BITMAP_FLAG, filter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHinting(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return Paint.HINTING_ON;
-        }
-
-        return delegate.mHintingMode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHinting(long nativePaint, int mode) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mHintingMode = mode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAntiAlias(long nativePaint, boolean aa) {
-        setFlag(nativePaint, Paint.ANTI_ALIAS_FLAG, aa);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetSubpixelText(long nativePaint,
-            boolean subpixelText) {
-        setFlag(nativePaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetUnderlineText(long nativePaint,
-            boolean underlineText) {
-        setFlag(nativePaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrikeThruText(long nativePaint,
-            boolean strikeThruText) {
-        setFlag(nativePaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFakeBoldText(long nativePaint,
-            boolean fakeBoldText) {
-        setFlag(nativePaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetDither(long nativePaint, boolean dither) {
-        setFlag(nativePaint, Paint.DITHER_FLAG, dither);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLinearText(long nativePaint, boolean linearText) {
-        setFlag(nativePaint, Paint.LINEAR_TEXT_FLAG, linearText);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetColor(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mColor;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetColor(long nativePaint, int color) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mColor = color;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetAlpha(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getAlpha();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetAlpha(long nativePaint, int a) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.setAlpha(a);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeWidth(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeWidth;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeWidth(long nativePaint, float width) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeWidth = width;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetStrokeMiter(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mStrokeMiter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeMiter(long nativePaint, float miter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStrokeMiter = miter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetShadowLayer(long paint, float radius, float dx, float dy,
-            int color) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.setShadowLayer is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasShadowLayer(long paint) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.hasShadowLayer is not supported.", null, null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsElegantTextHeight(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetElegantTextHeight(long nativePaint,
-            boolean elegant) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSize(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSize;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSize(long nativePaint, float textSize) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSize != textSize) {
-            delegate.mTextSize = textSize;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextScaleX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextScaleX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextScaleX(long nativePaint, float scaleX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextScaleX != scaleX) {
-            delegate.mTextScaleX = scaleX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextSkewX(long nativePaint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 1.f;
-        }
-
-        return delegate.mTextSkewX;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextSkewX(long nativePaint, float skewX) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (delegate.mTextSkewX != skewX) {
-            delegate.mTextSkewX = skewX;
-            delegate.updateFontObject();
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAscent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            // Android expects negative ascent so we invert the value from Java.
-            return - javaMetrics.getAscent();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nDescent(long nativePaint, long nativeTypeface) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            return javaMetrics.getDescent();
-        }
-
-        return 0;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetFontMetrics(long nativePaint, long nativeTypeface,
-            FontMetrics metrics) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.getFontMetrics(metrics);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFontMetricsInt(long nativePaint,
-            long nativeTypeface, FontMetricsInt fmi) {
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        if (delegate.mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
-            if (fmi != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                fmi.top = - javaMetrics.getMaxAscent();
-                fmi.ascent = - javaMetrics.getAscent();
-                fmi.descent = javaMetrics.getDescent();
-                fmi.bottom = javaMetrics.getMaxDescent();
-                fmi.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, char[] text,
-            int index, int count, float maxWidth, int bidiFlags, float[] measuredWidth) {
-
-        // get the delegate
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        int inc = count > 0 ? 1 : -1;
-
-        int measureIndex = 0;
-        for (int i = index; i != index + count; i += inc, measureIndex++) {
-            int start, end;
-            if (i < index) {
-                start = i;
-                end = index;
-            } else {
-                start = index;
-                end = i;
-            }
-
-            // measure from start to end
-            RectF bounds = delegate.measureText(text, start, end - start + 1, null, 0, bidiFlags);
-            float res = bounds.right - bounds.left;
-
-            if (measuredWidth != null) {
-                measuredWidth[measureIndex] = res;
-            }
-
-            if (res > maxWidth) {
-                // we should not return this char index, but since it's 0-based
-                // and we need to return a count, we simply return measureIndex;
-                return measureIndex;
-            }
-
-        }
-
-        return measureIndex;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nBreakText(long nativePaint, long nativeTypeface, String text,
-            boolean measureForwards,
-            float maxWidth, int bidiFlags, float[] measuredWidth) {
-        return nBreakText(nativePaint, nativeTypeface, text.toCharArray(), 0, text.length(),
-                maxWidth, bidiFlags, measuredWidth);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        Paint_Delegate newDelegate = new Paint_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInitWithPaint(long paint) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(paint);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long native_src) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
-        if (delegate_dst == null) {
-            return;
-        }
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
-        if (delegate_src == null) {
-            return;
-        }
-
-        delegate_dst.set(delegate_src);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStyle(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStyle(long native_object, int style) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mStyle = style;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeCap(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mCap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeCap(long native_object, int cap) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mCap = cap;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetStrokeJoin(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mJoin;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetStrokeJoin(long native_object, int join) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mJoin = join;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nGetFillPath(long native_object, long src, long dst) {
-        Paint_Delegate paint = sManager.getDelegate(native_object);
-        if (paint == null) {
-            return false;
-        }
-
-        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
-        if (srcPath == null) {
-            return true;
-        }
-
-        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
-        if (dstPath == null) {
-            return true;
-        }
-
-        Stroke stroke = paint.getJavaStroke();
-        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
-
-        dstPath.setJavaShape(strokeShape);
-
-        // FIXME figure out the return value?
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetShader(long native_object, long shader) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return shader;
-        }
-
-        delegate.mShader = Shader_Delegate.getDelegate(shader);
-
-        return shader;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetColorFilter(long native_object, long filter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return filter;
-        }
-
-        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);
-
-        // Log warning if it's not supported.
-        if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
-                    delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return filter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetXfermode(long native_object, int xfermode) {
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mPorterDuffMode = xfermode;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetPathEffect(long native_object, long effect) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return effect;
-        }
-
-        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
-
-        return effect;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetMaskFilter(long native_object, long maskfilter) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return maskfilter;
-        }
-
-        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
-
-        // since none of those are supported, display a fidelity warning right away
-        if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
-                    delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
-        }
-
-        return maskfilter;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nSetTypeface(long native_object, long typeface) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        Typeface_Delegate typefaceDelegate = Typeface_Delegate.getDelegate(typeface);
-        if (delegate.mTypeface != typefaceDelegate || delegate.mNativeTypeface != typeface) {
-            delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
-            delegate.mNativeTypeface = typeface;
-            delegate.updateFontObject();
-        }
-        return typeface;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextAlign(long native_object) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mTextAlign;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextAlign(long native_object, int align) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return;
-        }
-
-        delegate.mTextAlign = align;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nSetTextLocales(long native_object, String locale) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0;
-        }
-
-        delegate.setTextLocale(locale);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetTextLocalesByMinikinLangListId(long paintPtr,
-            int mMinikinLangListId) {
-        // FIXME
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            char[] text, int index, int count, int contextIndex, int contextCount,
-            int bidiFlags, float[] advances, int advancesIndex) {
-
-        if (advances != null)
-            for (int i = advancesIndex; i< advancesIndex+count; i++)
-                advances[i]=0;
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(native_object);
-        if (delegate == null) {
-            return 0.f;
-        }
-
-        // native_typeface is passed here since Framework's old implementation did not have the
-        // typeface object associated with the Paint. Since, we follow the new framework way,
-        // we store the typeface with the paint and use it directly.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        RectF bounds = delegate.measureText(text, index, count, advances, advancesIndex, bidiFlags);
-        return bounds.right - bounds.left;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTextAdvances(long native_object, long native_typeface,
-            String text, int start, int end, int contextStart, int contextEnd,
-            int bidiFlags, float[] advances, int advancesIndex) {
-        // FIXME: support contextStart and contextEnd
-        int count = end - start;
-        char[] buffer = TemporaryBuffer.obtain(count);
-        TextUtils.getChars(text, start, end, buffer, 0);
-
-        return nGetTextAdvances(native_object, native_typeface, buffer, 0, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, advancesIndex);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            char[] text, int contextStart, int contextLength, int flags, int offset,
-            int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, long typefacePtr,
-            String text, int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextRunCursor is not supported.", null, null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetTextPath(long native_object, long native_typeface,
-            int bidiFlags, String text, int start, int end, float x, float y, long path) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Paint.getTextPath is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetStringBounds(long nativePaint, long native_typeface,
-            String text, int start, int end, int bidiFlags, Rect bounds) {
-        nGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
-                end - start, bidiFlags, bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetCharArrayBounds(long nativePaint, long native_typeface,
-            char[] text, int index, int count, int bidiFlags, Rect bounds) {
-
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        // assert that the typeface passed is actually the one that we had stored.
-        assert (native_typeface == delegate.mNativeTypeface);
-
-        delegate.measureText(text, index, count, null, 0, bidiFlags).roundOut(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (Paint_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(
-                        sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetLetterSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mLetterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setLetterSpacing() not supported.", null, null);
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mLetterSpacing = letterSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetWordSpacing(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mWordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mWordSpacing = wordSpacing;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setFontFeatureSettings() not supported.", null, null);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetHyphenEdit(long nativePaint) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mHyphenEdit;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetHyphenEdit(long nativePaint, int hyphen) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-        delegate.mHyphenEdit = hyphen;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nHasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
-            String string) {
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return false;
-        }
-        if (string.length() == 0) {
-            return false;
-        }
-        if (string.length() > 1) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                    "Paint.hasGlyph() is not supported for ligatures.", null, null);
-            return false;
-        }
-        assert nativeTypeface == delegate.mNativeTypeface;
-        Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
-
-        char c = string.charAt(0);
-        for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
-            if (font.canDisplay(c)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRunAdvance(long nativePaint, long nativeTypeface,
-            @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
-            boolean isRtl, int offset) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        int startOffset = offset - start;  // offset from start.
-        float sum = 0;
-        for (int i = 0; i < startOffset; i++) {
-            sum += advances[i];
-        }
-        return sum;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetOffsetForAdvance(long nativePaint, long nativeTypeface,
-            char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
-            float advance) {
-        int count = end - start;
-        float[] advances = new float[count];
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        nGetTextAdvances(nativePaint, nativeTypeface, text, start, count,
-                contextStart, contextEnd - contextStart, bidiFlags, advances, 0);
-        float sum = 0;
-        int i;
-        for (i = 0; i < count && sum < advance; i++) {
-            sum += advances[i];
-        }
-        float distanceToI = sum - advance;
-        float distanceToIMinus1 = advance - (sum - advances[i]);
-        return distanceToI > distanceToIMinus1 ? i : i - 1;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /*package*/ Paint_Delegate() {
-        reset();
-    }
-
-    private Paint_Delegate(Paint_Delegate paint) {
-        set(paint);
-    }
-
-    private void set(Paint_Delegate paint) {
-        mFlags = paint.mFlags;
-        mColor = paint.mColor;
-        mStyle = paint.mStyle;
-        mCap = paint.mCap;
-        mJoin = paint.mJoin;
-        mTextAlign = paint.mTextAlign;
-
-        boolean needsFontUpdate = false;
-        if (mTypeface != paint.mTypeface || mNativeTypeface != paint.mNativeTypeface) {
-            mTypeface = paint.mTypeface;
-            mNativeTypeface = paint.mNativeTypeface;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSize != paint.mTextSize) {
-            mTextSize = paint.mTextSize;
-            needsFontUpdate = true;
-        }
-
-        if (mTextScaleX != paint.mTextScaleX) {
-            mTextScaleX = paint.mTextScaleX;
-            needsFontUpdate = true;
-        }
-
-        if (mTextSkewX != paint.mTextSkewX) {
-            mTextSkewX = paint.mTextSkewX;
-            needsFontUpdate = true;
-        }
-
-        mStrokeWidth = paint.mStrokeWidth;
-        mStrokeMiter = paint.mStrokeMiter;
-        mPorterDuffMode = paint.mPorterDuffMode;
-        mColorFilter = paint.mColorFilter;
-        mShader = paint.mShader;
-        mPathEffect = paint.mPathEffect;
-        mMaskFilter = paint.mMaskFilter;
-        mHintingMode = paint.mHintingMode;
-
-        if (needsFontUpdate) {
-            updateFontObject();
-        }
-    }
-
-    private void reset() {
-        mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
-        mColor = 0xFF000000;
-        mStyle = Paint.Style.FILL.nativeInt;
-        mCap = Paint.Cap.BUTT.nativeInt;
-        mJoin = Paint.Join.MITER.nativeInt;
-        mTextAlign = 0;
-        mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
-        mNativeTypeface = 0;
-        mStrokeWidth = 1.f;
-        mStrokeMiter = 4.f;
-        mTextSize = 20.f;
-        mTextScaleX = 1.f;
-        mTextSkewX = 0.f;
-        mPorterDuffMode = Xfermode.DEFAULT;
-        mColorFilter = null;
-        mShader = null;
-        mPathEffect = null;
-        mMaskFilter = null;
-        updateFontObject();
-        mHintingMode = Paint.HINTING_ON;
-    }
-
-    /**
-     * Update the {@link Font} object from the typeface, text size and scaling
-     */
-    @SuppressWarnings("deprecation")
-    private void updateFontObject() {
-        if (mTypeface != null) {
-            // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts(mFontVariant);
-
-            if (fonts.isEmpty()) {
-                mFonts = Collections.emptyList();
-                return;
-            }
-
-            // create new font objects as well as FontMetrics, based on the current text size
-            // and skew info.
-            int nFonts = fonts.size();
-            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(nFonts);
-            //noinspection ForLoopReplaceableByForEach (avoid iterator instantiation)
-            for (int i = 0; i < nFonts; i++) {
-                Font font = fonts.get(i);
-                if (font == null) {
-                    // If the font is null, add null to infoList. When rendering the text, if this
-                    // null is reached, a warning will be logged.
-                    infoList.add(null);
-                    continue;
-                }
-                FontInfo info = new FontInfo();
-                info.mFont = font.deriveFont(mTextSize);
-                if (mTextScaleX != 1.0 || mTextSkewX != 0) {
-                    // TODO: support skew
-                    info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mTextScaleX, mTextSkewX, 0, 1, 0, 0));
-                }
-                // The metrics here don't have anti-aliasing set.
-                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
-
-                infoList.add(info);
-            }
-
-            mFonts = Collections.unmodifiableList(infoList);
-        }
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, int bidiFlags) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, bidiFlags, advances, advancesIndex, false);
-    }
-
-    /*package*/ RectF measureText(char[] text, int index, int count, float[] advances,
-            int advancesIndex, boolean isRtl) {
-        return new BidiRenderer(null, this, text)
-                .renderText(index, index + count, isRtl, advances, advancesIndex, false);
-    }
-
-    private float getFontMetrics(FontMetrics metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    private void setTextLocale(String locale) {
-        mLocale = new Locale(locale);
-    }
-
-    private static void setFlag(long nativePaint, int flagMask, boolean flagValue) {
-        // get the delegate from the native int.
-        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
-        if (delegate == null) {
-            return;
-        }
-
-        if (flagValue) {
-            delegate.mFlags |= flagMask;
-        } else {
-            delegate.mFlags &= ~flagMask;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
deleted file mode 100644
index fd9ba62e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathDashPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathDashPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Path Dash Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long native_path, float advance, float phase,
-            int native_style) {
-        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
deleted file mode 100644
index 000481e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.PathEffect
- *
- * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PathEffect class.
- *
- * This also serve as a base class for all PathEffect delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class PathEffect_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<PathEffect_Delegate> sManager =
-            new DelegateManager<PathEffect_Delegate>(PathEffect_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    public static PathEffect_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public abstract Stroke getStroke(Paint_Delegate paint);
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_patheffect) {
-        sManager.removeJavaReferenceFor(native_patheffect);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
deleted file mode 100644
index 7f707c9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PathMeasure_Delegate.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator;
-
-import java.awt.geom.PathIterator;
-
-/**
- * Delegate implementing the native methods of {@link android.graphics.PathMeasure}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of PathMeasure have been
- * replaced by
- * calls to methods of the same name in this delegate class.
- * <p/>
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between it
- * and the original PathMeasure class.
- *
- * @see DelegateManager
- */
-public final class PathMeasure_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<PathMeasure_Delegate> sManager =
-            new DelegateManager<PathMeasure_Delegate>(PathMeasure_Delegate.class);
-
-    // ---- delegate data ----
-    private CachedPathIteratorFactory mOriginalPathIterator;
-
-    private long mNativePath;
-
-
-    private PathMeasure_Delegate(long native_path, boolean forceClosed) {
-        mNativePath = native_path;
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_create(long native_path, boolean forceClosed) {
-        return sManager.addNewDelegate(new PathMeasure_Delegate(native_path, forceClosed));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_destroy(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getPosTan(long native_instance, float distance, float pos[],
-            float tan[]) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getPostTan is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getMatrix(long native_instance, float distance, long
-            native_matrix, int flags) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.getMatrix is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_nextContour(long native_instance) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "PathMeasure.nextContour is not supported.", null, null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_setPath(long native_instance, long native_path, boolean
-            forceClosed) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (native_path != 0) {
-            if (forceClosed) {
-                // Copy the path and call close
-                native_path = Path_Delegate.nInit(native_path);
-                Path_Delegate.nClose(native_path);
-            }
-
-            Path_Delegate pathDelegate = Path_Delegate.getDelegate(native_path);
-            pathMeasure.mOriginalPathIterator = new CachedPathIteratorFactory(pathDelegate.getJavaShape()
-                    .getPathIterator(null));
-        }
-
-        pathMeasure.mNativePath = native_path;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float native_getLength(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        if (pathMeasure.mOriginalPathIterator == null) {
-            return 0;
-        }
-
-        return pathMeasure.mOriginalPathIterator.iterator().getTotalLength();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_isClosed(long native_instance) {
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        Path_Delegate path = Path_Delegate.getDelegate(pathMeasure.mNativePath);
-        if (path == null) {
-            return false;
-        }
-
-        int type = 0;
-        float segment[] = new float[6];
-        for (PathIterator pi = path.getJavaShape().getPathIterator(null); !pi.isDone(); pi.next()) {
-            type = pi.currentSegment(segment);
-        }
-
-        // A path is a closed path if the last element is SEG_CLOSE
-        return type == PathIterator.SEG_CLOSE;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean native_getSegment(long native_instance, float startD, float stopD,
-            long native_dst_path, boolean startWithMoveTo) {
-        if (startD < 0) {
-            startD = 0;
-        }
-
-        if (startD >= stopD) {
-            return false;
-        }
-
-        PathMeasure_Delegate pathMeasure = sManager.getDelegate(native_instance);
-        assert pathMeasure != null;
-
-        CachedPathIterator iterator = pathMeasure.mOriginalPathIterator.iterator();
-        float accLength = startD;
-        boolean isZeroLength = true; // Whether the output has zero length or not
-        float[] points = new float[6];
-
-        iterator.jumpToSegment(accLength);
-        while (!iterator.isDone() && (stopD - accLength > 0.1f)) {
-            int type = iterator.currentSegment(points, stopD - accLength);
-
-            if (accLength - iterator.getCurrentSegmentLength() <= stopD) {
-                if (startWithMoveTo) {
-                    startWithMoveTo = false;
-
-                    // If this segment is a MOVETO, then we just use that one. If not, then we issue
-                    // a first moveto
-                    if (type != PathIterator.SEG_MOVETO) {
-                        float[] lastPoint = new float[2];
-                        iterator.getCurrentSegmentEnd(lastPoint);
-                        Path_Delegate.nMoveTo(native_dst_path, lastPoint[0], lastPoint[1]);
-                    }
-                }
-
-                isZeroLength = isZeroLength && iterator.getCurrentSegmentLength() > 0;
-                switch (type) {
-                    case PathIterator.SEG_MOVETO:
-                        Path_Delegate.nMoveTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_LINETO:
-                        Path_Delegate.nLineTo(native_dst_path, points[0], points[1]);
-                        break;
-                    case PathIterator.SEG_CLOSE:
-                        Path_Delegate.nClose(native_dst_path);
-                        break;
-                    case PathIterator.SEG_CUBICTO:
-                        Path_Delegate.nCubicTo(native_dst_path, points[0], points[1],
-                                points[2], points[3],
-                                points[4], points[5]);
-                        break;
-                    case PathIterator.SEG_QUADTO:
-                        Path_Delegate.nQuadTo(native_dst_path, points[0], points[1],
-                                points[2],
-                                points[3]);
-                        break;
-                    default:
-                        assert false;
-                }
-            }
-
-            accLength += iterator.getCurrentSegmentLength();
-            iterator.next();
-        }
-
-        return !isZeroLength;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
deleted file mode 100644
index 50b9165..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path.Direction;
-import android.graphics.Path.FillType;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Area;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Path2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RoundRectangle2D;
-import java.util.ArrayList;
-
-/**
- * Delegate implementing the native methods of android.graphics.Path
- *
- * Through the layoutlib_create tool, the original native methods of Path have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Path class.
- *
- * @see DelegateManager
- *
- */
-public final class Path_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Path_Delegate> sManager =
-            new DelegateManager<Path_Delegate>(Path_Delegate.class);
-
-    private static final float EPSILON = 1e-4f;
-
-    // ---- delegate data ----
-    private FillType mFillType = FillType.WINDING;
-    private Path2D mPath = new Path2D.Double();
-
-    private float mLastX = 0;
-    private float mLastY = 0;
-
-    // true if the path contains does not contain a curve or line.
-    private boolean mCachedIsEmpty = true;
-
-    // ---- Public Helper methods ----
-
-    public static Path_Delegate getDelegate(long nPath) {
-        return sManager.getDelegate(nPath);
-    }
-
-    public Path2D getJavaShape() {
-        return mPath;
-    }
-
-    public void setJavaShape(Shape shape) {
-        reset();
-        mPath.append(shape, false /*connect*/);
-    }
-
-    public void reset() {
-        mPath.reset();
-        mLastX = 0;
-        mLastY = 0;
-    }
-
-    public void setPathIterator(PathIterator iterator) {
-        reset();
-        mPath.append(iterator, false /*connect*/);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit() {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nInit(long nPath) {
-        // create the delegate
-        Path_Delegate newDelegate = new Path_Delegate();
-
-        // get the delegate to copy, which could be null if nPath is 0
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate != null) {
-            newDelegate.set(pathDelegate);
-        }
-
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.reset();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRewind(long nPath) {
-        // call out to reset since there's nothing to optimize in
-        // terms of data structs.
-        nReset(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSet(long native_dst, long nSrc) {
-        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
-        if (pathDstDelegate == null) {
-            return;
-        }
-
-        Path_Delegate pathSrcDelegate = sManager.getDelegate(nSrc);
-        if (pathSrcDelegate == null) {
-            return;
-        }
-
-        pathDstDelegate.set(pathSrcDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsConvex(long nPath) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Path.isConvex is not supported.", null, null);
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nGetFillType(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return 0;
-        }
-
-        return pathDelegate.mFillType.nativeInt;
-    }
-
-    @LayoutlibDelegate
-    public static void nSetFillType(long nPath, int ft) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.setFillType(Path.sFillTypeArray[ft]);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsEmpty(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        return pathDelegate == null || pathDelegate.isEmpty();
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsRect(long nPath, RectF rect) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return false;
-        }
-
-        // create an Area that can test if the path is a rect
-        Area area = new Area(pathDelegate.mPath);
-        if (area.isRectangular()) {
-            if (rect != null) {
-                pathDelegate.fillBounds(rect);
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nComputeBounds(long nPath, RectF bounds) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.fillBounds(bounds);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nIncReserve(long nPath, int extraPtCount) {
-        // since we use a java2D path, there's no way to pre-allocate new points,
-        // so we do nothing.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nMoveTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.moveTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRMoveTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rMoveTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nLineTo(long nPath, float x, float y) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.lineTo(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRLineTo(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rLineTo(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nQuadTo(long nPath, float x1, float y1, float x2, float y2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.quadTo(x1, y1, x2, y2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nRCubicTo(long nPath, float x1, float y1,
-            float x2, float y2, float x3, float y3) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nArcTo(long nPath, float left, float top, float right,
-            float bottom,
-                    float startAngle, float sweepAngle, boolean forceMoveTo) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.arcTo(left, top, right, bottom, startAngle, sweepAngle, forceMoveTo);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nClose(long nPath) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.close();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRect(long nPath,
-            float left, float top, float right, float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.addRect(left, top, right, bottom, dir);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddOval(long nPath, float left, float top, float right,
-            float bottom, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                left, top, right - left, bottom - top), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddCircle(long nPath, float x, float y, float radius, int dir) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Ellipse2D.Float(
-                x - radius, y - radius, radius * 2, radius * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddArc(long nPath, float left, float top, float right,
-            float bottom, float startAngle, float sweepAngle) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        // because x/y is the center of the circle, need to offset this by the radius
-        pathDelegate.mPath.append(new Arc2D.Float(
-                left, top, right - left, bottom - top,
-                -startAngle, -sweepAngle, Arc2D.OPEN), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float rx, float ry, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mPath.append(new RoundRectangle2D.Float(
-                left, top, right - left, bottom - top, rx * 2, ry * 2), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddRoundRect(long nPath, float left, float top, float right,
-            float bottom, float[] radii, int dir) {
-
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        float[] cornerDimensions = new float[radii.length];
-        for (int i = 0; i < radii.length; i++) {
-            cornerDimensions[i] = 2 * radii[i];
-        }
-        pathDelegate.mPath.append(new RoundRectangle(left, top, right - left, bottom - top,
-                cornerDimensions), false);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, float dx, float dy) {
-        addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src) {
-        addPath(nPath, src, null /*transform*/);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddPath(long nPath, long src, long matrix) {
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        addPath(nPath, src, matrixDelegate.getAffineTransform());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nOffset(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.offset(dx, dy);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLastPoint(long nPath, float dx, float dy) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        pathDelegate.mLastX = dx;
-        pathDelegate.mLastY = dy;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix,
-                                                long dst_path) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return;
-        }
-
-        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
-        if (matrixDelegate == null) {
-            return;
-        }
-
-        // this can be null if dst_path is 0
-        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
-
-        pathDelegate.transform(matrixDelegate, dstDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nTransform(long nPath, long matrix) {
-        nTransform(nPath, matrix, 0);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nOp(long nPath1, long nPath2, int op, long result) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nPath) {
-        sManager.removeJavaReferenceFor(nPath);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float[] nApproximate(long nPath, float error) {
-        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
-        if (pathDelegate == null) {
-            return null;
-        }
-        // Get a FlatteningIterator
-        PathIterator iterator = pathDelegate.getJavaShape().getPathIterator(null, error);
-
-        float segment[] = new float[6];
-        float totalLength = 0;
-        ArrayList<Point2D.Float> points = new ArrayList<Point2D.Float>();
-        Point2D.Float previousPoint = null;
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            Point2D.Float currentPoint = new Point2D.Float(segment[0], segment[1]);
-            // MoveTo shouldn't affect the length
-            if (previousPoint != null && type != PathIterator.SEG_MOVETO) {
-                totalLength += currentPoint.distance(previousPoint);
-            }
-            previousPoint = currentPoint;
-            points.add(currentPoint);
-            iterator.next();
-        }
-
-        int nPoints = points.size();
-        float[] result = new float[nPoints * 3];
-        previousPoint = null;
-        for (int i = 0; i < nPoints; i++) {
-            Point2D.Float point = points.get(i);
-            float distance = previousPoint != null ? (float) previousPoint.distance(point) : .0f;
-            result[i * 3] = distance / totalLength;
-            result[i * 3 + 1] = point.x;
-            result[i * 3 + 2] = point.y;
-
-            totalLength += distance;
-            previousPoint = point;
-        }
-
-        return result;
-    }
-
-    // ---- Private helper methods ----
-
-    private void set(Path_Delegate delegate) {
-        mPath.reset();
-        setFillType(delegate.mFillType);
-        mPath.append(delegate.mPath, false /*connect*/);
-    }
-
-    private void setFillType(FillType fillType) {
-        mFillType = fillType;
-        mPath.setWindingRule(getWindingRule(fillType));
-    }
-
-    /**
-     * Returns the Java2D winding rules matching a given Android {@link FillType}.
-     * @param type the android fill type
-     * @return the matching java2d winding rule.
-     */
-    private static int getWindingRule(FillType type) {
-        switch (type) {
-            case WINDING:
-            case INVERSE_WINDING:
-                return GeneralPath.WIND_NON_ZERO;
-            case EVEN_ODD:
-            case INVERSE_EVEN_ODD:
-                return GeneralPath.WIND_EVEN_ODD;
-
-            default:
-                assert false;
-                return GeneralPath.WIND_NON_ZERO;
-        }
-    }
-
-    @NonNull
-    private static Direction getDirection(int direction) {
-        for (Direction d : Direction.values()) {
-            if (direction == d.nativeInt) {
-                return d;
-            }
-        }
-
-        assert false;
-        return null;
-    }
-
-    public static void addPath(long destPath, long srcPath, AffineTransform transform) {
-        Path_Delegate destPathDelegate = sManager.getDelegate(destPath);
-        if (destPathDelegate == null) {
-            return;
-        }
-
-        Path_Delegate srcPathDelegate = sManager.getDelegate(srcPath);
-        if (srcPathDelegate == null) {
-            return;
-        }
-
-        if (transform != null) {
-            destPathDelegate.mPath.append(
-                    srcPathDelegate.mPath.getPathIterator(transform), false);
-        } else {
-            destPathDelegate.mPath.append(srcPathDelegate.mPath, false);
-        }
-    }
-
-
-    /**
-     * Returns whether the path already contains any points.
-     * Note that this is different to
-     * {@link #isEmpty} because if all elements are {@link PathIterator#SEG_MOVETO},
-     * {@link #isEmpty} will return true while hasPoints will return false.
-     */
-    public boolean hasPoints() {
-        return !mPath.getPathIterator(null).isDone();
-    }
-
-    /**
-     * Returns whether the path is empty (contains no lines or curves).
-     * @see Path#isEmpty
-     */
-    public boolean isEmpty() {
-        if (!mCachedIsEmpty) {
-            return false;
-        }
-
-        float[] coords = new float[6];
-        mCachedIsEmpty = Boolean.TRUE;
-        for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
-            int type = it.currentSegment(coords);
-            if (type != PathIterator.SEG_MOVETO) {
-                // Once we know that the path is not empty, we do not need to check again unless
-                // Path#reset is called.
-                mCachedIsEmpty = false;
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Fills the given {@link RectF} with the path bounds.
-     * @param bounds the RectF to be filled.
-     */
-    public void fillBounds(RectF bounds) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    public void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    public void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    public void lineTo(float x, float y) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    public void rLineTo(float dx, float dy) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-
-        if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON) {
-            // The delta is so small that this shouldn't generate a line
-            return;
-        }
-
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    public void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        if (!hasPoints()) {
-            mPath.moveTo(0, 0);
-        }
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (!hasPoints()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param left        The left of oval defining shape and size of the arc
-     * @param top         The top of oval defining shape and size of the arc
-     * @param right       The right of oval defining shape and size of the arc
-     * @param bottom      The bottom of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    public void arcTo(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle,
-            boolean forceMoveTo) {
-        Arc2D arc = new Arc2D.Float(left, top, right - left, bottom - top, -startAngle,
-                -sweepAngle, Arc2D.OPEN);
-        mPath.append(arc, true /*connect*/);
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    public void close() {
-        mPath.closePath();
-    }
-
-    private void resetLastPointFromPath() {
-        Point2D last = mPath.getCurrentPoint();
-        mLastX = (float) last.getX();
-        mLastY = (float) last.getY();
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    public void addRect(float left, float top, float right, float bottom,
-                        int dir) {
-        moveTo(left, top);
-
-        Direction direction = getDirection(dir);
-
-        switch (direction) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-
-        resetLastPointFromPath();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     */
-    public void offset(float dx, float dy) {
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-
-        newPath.append(iterator, false /*connect*/);
-        mPath = newPath;
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
-        if (matrix.hasPerspective()) {
-            assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
-                    "android.graphics.Path#transform() only " +
-                    "supports affine transformations.", null, null /*data*/);
-        }
-
-        GeneralPath newPath = new GeneralPath();
-
-        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
-
-        newPath.append(iterator, false /*connect*/);
-
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
deleted file mode 100644
index ff3f19f..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.PorterDuff.Mode;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getComposite;
-import static com.android.layoutlib.bridge.impl.PorterDuffUtility.getPorterDuffMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.PorterDuffColorFilter
- *
- * Through the layoutlib_create tool, the original native methods of PorterDuffColorFilter have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original PorterDuffColorFilter class.
- *
- * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
- * {@link DelegateManager}, as all the Shader classes will be added to the manager
- * owned by {@link ColorFilter_Delegate}.
- *
- * @see ColorFilter_Delegate
- *
- */
-public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
-
-    // ---- delegate data ----
-
-    private final java.awt.Color mSrcColor;
-    private final Mode mMode;
-
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "PorterDuff Color Filter is not supported for mode: " + mMode.name() + ".";
-    }
-
-    @Override
-    public void applyFilter(Graphics2D g, int width, int height) {
-        g.setComposite(getComposite(mMode, 0xFF));
-        g.setColor(mSrcColor);
-        g.fillRect(0, 0, width, height);
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) {
-        PorterDuffColorFilter_Delegate newDelegate =
-                new PorterDuffColorFilter_Delegate(srcColor, porterDuffMode);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-
-    // ---- Private delegate/helper methods ----
-
-    private PorterDuffColorFilter_Delegate(int srcColor, int mode) {
-        mSrcColor = new java.awt.Color(srcColor, true /* hasAlpha */);
-        mMode = getCompatibleMode(getPorterDuffMode(mode));
-    }
-
-    // For filtering the colors, the src image should contain the "color" only for pixel values
-    // which are not transparent in the target image. But, we are using a simple rectangular image
-    // completely filled with color. Hence some Composite rules do not apply as intended. However,
-    // in such cases, they can usually be mapped to some other mode, which produces an approximately
-    // equivalent result.
-    private Mode getCompatibleMode(Mode mode) {
-        Mode m = mode;
-        // Modes that are directly supported:
-        // CLEAR, DST, SRC_IN, DST_IN, DST_OUT, SRC_ATOP, DARKEN, LIGHTEN, MULTIPLY, SCREEN,
-        // ADD, OVERLAY
-        switch (mode) {
-        // Modes that can be mapped to one of the supported modes.
-        case SRC:
-            m = Mode.SRC_IN;
-            break;
-        case SRC_OVER:
-            m = Mode.SRC_ATOP;
-            break;
-        case DST_OVER:
-            m = Mode.DST;
-            break;
-        case SRC_OUT:
-            m = Mode.CLEAR;
-            break;
-        case DST_ATOP:
-            m = Mode.DST_IN;
-            break;
-        case XOR:
-            m = Mode.DST_OUT;
-            break;
-        }
-        return m;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
deleted file mode 100644
index b5ba468..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-import java.awt.image.ColorModel;
-
-/**
- * Delegate implementing the native methods of android.graphics.RadialGradient
- *
- * Through the layoutlib_create tool, the original native methods of RadialGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original RadialGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class RadialGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, float radius,
-            int colors[], float positions[], int tileMode) {
-        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(matrix, x, y, radius,
-                colors, positions, Shader_Delegate.getTileMode(tileMode));
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, float radius,
-            int color0, int color1, int tileMode) {
-        return nativeCreate1(matrix, x, y, radius, new int[] { color0, color1 },
-                null /*positions*/, tileMode);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param colors The colors to be distributed between the center and edge of
-     *            the circle
-     * @param positions May be NULL. The relative position of each corresponding
-     *            color in the colors array. If this is NULL, the the colors are
-     *            distributed evenly between the center and edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    private RadialGradient_Delegate(long nativeMatrix, float x, float y, float radius,
-            int colors[], float positions[], TileMode tile) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
-    }
-
-    private class RadialGradientPaint extends GradientPaint {
-
-        private final float mX;
-        private final float mY;
-        private final float mRadius;
-
-        public RadialGradientPaint(float x, float y, float radius,
-                int[] colors, float[] positions, TileMode mode) {
-            super(colors, positions, mode);
-            mX = x;
-            mY = y;
-            mRadius = radius;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class RadialGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public RadialGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel.hasAlpha() ? colorModel : ColorModel.getRGBdefault();
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute distance from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mX;
-                        pt1[1] = pt2[1] - mY;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float _x = pt2[0];
-                        float _y = pt2[1];
-                        float distance = (float) Math.hypot(_x, _y);
-
-                        data[index++] = getGradientColor(distance / mRadius);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
deleted file mode 100644
index edb7025..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.os.Parcel;
-
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Delegate implementing the native methods of android.graphics.Region
- *
- * Through the layoutlib_create tool, the original native methods of Region have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Region class.
- *
- * This also serve as a base class for all Region delegate classes.
- *
- * @see DelegateManager
- *
- */
-public class Region_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Region_Delegate> sManager =
-            new DelegateManager<Region_Delegate>(Region_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Area mArea = new Area();
-
-    // ---- Public Helper methods ----
-
-    public static Region_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    public Area getJavaArea() {
-        return mArea;
-    }
-
-    /**
-     * Combines two {@link Shape} into another one (actually an {@link Area}), according
-     * to the given {@link Region.Op}.
-     *
-     * If the Op is not one that combines two shapes, then this return null
-     *
-     * @param shape1 the firt shape to combine which can be null if there's no original clip.
-     * @param shape2 the 2nd shape to combine
-     * @param regionOp the operande for the combine
-     * @return a new area or null.
-     */
-    public static Area combineShapes(Shape shape1, Shape shape2, int regionOp) {
-        if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
-            // if shape1 is null (empty), then the result is null.
-            if (shape1 == null) {
-                return null;
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.subtract(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.INTERSECT.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.intersect(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.UNION.nativeInt) {
-            // if shape1 is null, then the result is simply shape2.
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.add(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.XOR.nativeInt) {
-            // if shape1 is null, then the result is simply shape2
-            if (shape1 == null) {
-                return new Area(shape2);
-            }
-
-            // result is always a new area.
-            Area result = new Area(shape1);
-            result.exclusiveOr(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
-            return result;
-
-        } else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
-            // result is always a new area.
-            Area result = new Area(shape2);
-
-            if (shape1 != null) {
-                result.subtract(shape1 instanceof Area ? (Area) shape1 : new Area(shape1));
-            }
-
-            return result;
-        }
-
-        return null;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isEmpty(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isEmpty();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isRect(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isRectangular();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isComplex(Region thisRegion) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return true;
-        }
-
-        return regionDelegate.mArea.isSingular() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean contains(Region thisRegion, int x, int y) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.contains(x, y);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickContains(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isRectangular() &&
-                regionDelegate.mArea.contains(left, top, right - left, bottom - top);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion,
-            int left, int top, int right, int bottom) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return false;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return false;
-        }
-
-        return regionDelegate.mArea.isEmpty() ||
-                regionDelegate.mArea.getBounds().intersects(
-                        targetRegionDelegate.mArea.getBounds()) == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.translate(dx, dy);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
-        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
-        if (regionDelegate == null) {
-            return;
-        }
-
-        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
-        if (targetRegionDelegate == null) {
-            return;
-        }
-
-        if (regionDelegate.mArea.isEmpty()) {
-            targetRegionDelegate.mArea = new Area();
-        } else {
-            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
-            AffineTransform mtx = new AffineTransform();
-            mtx.scale(scale, scale);
-            targetRegionDelegate.mArea.transform(mtx);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeConstructor() {
-        Region_Delegate newDelegate = new Region_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeDestructor(long native_region) {
-        sManager.removeJavaReferenceFor(native_region);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetRegion(long native_dst, long native_src) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return;
-        }
-
-        Region_Delegate srcRegion = sManager.getDelegate(native_src);
-        if (srcRegion == null) {
-            return;
-        }
-
-        dstRegion.mArea.reset();
-        dstRegion.mArea.add(srcRegion.mArea);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRect(long native_dst,
-            int left, int top, int right, int bottom) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(new Rectangle2D.Float(left, top, right - left, bottom - top));
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeSetPath(long native_dst, long native_path, long native_clip) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return true;
-        }
-
-        dstRegion.mArea = new Area(path.getJavaShape());
-
-        Region_Delegate clip = sManager.getDelegate(native_clip);
-        if (clip != null) {
-            dstRegion.mArea.subtract(clip.getJavaArea());
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBounds(long native_region, Rect rect) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return true;
-        }
-
-        Rectangle bounds = region.mArea.getBounds();
-        if (bounds.isEmpty()) {
-            rect.left = rect.top = rect.right = rect.bottom = 0;
-            return false;
-        }
-
-        rect.left = bounds.x;
-        rect.top = bounds.y;
-        rect.right = bounds.x + bounds.width;
-        rect.bottom = bounds.y + bounds.height;
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeGetBoundaryPath(long native_region, long native_path) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return false;
-        }
-
-        Path_Delegate path = Path_Delegate.getDelegate(native_path);
-        if (path == null) {
-            return false;
-        }
-
-        if (region.mArea.isEmpty()) {
-            path.reset();
-            return false;
-        }
-
-        path.setPathIterator(region.mArea.getPathIterator(new AffineTransform()));
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            int left, int top, int right, int bottom, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(left, top, right - left, bottom - top), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst, Rect rect, long native_region, int op) {
-        Region_Delegate region = sManager.getDelegate(native_dst);
-        if (region == null) {
-            return false;
-        }
-
-        region.mArea = combineShapes(region.mArea,
-                new Rectangle2D.Float(rect.left, rect.top, rect.width(), rect.height()), op);
-
-        assert region.mArea != null;
-        if (region.mArea != null) {
-            region.mArea = new Area();
-        }
-
-        return region.mArea.getBounds().isEmpty() == false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeOp(long native_dst,
-            long native_region1, long native_region2, int op) {
-        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
-        if (dstRegion == null) {
-            return true;
-        }
-
-        Region_Delegate region1 = sManager.getDelegate(native_region1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_region2);
-        if (region2 == null) {
-            return false;
-        }
-
-        dstRegion.mArea = combineShapes(region1.mArea, region2.mArea, op);
-
-        assert dstRegion.mArea != null;
-        if (dstRegion.mArea != null) {
-            dstRegion.mArea = new Area();
-        }
-
-        return dstRegion.mArea.getBounds().isEmpty() == false;
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateFromParcel(Parcel p) {
-        // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
-        // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
-                null /*data*/);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeWriteToParcel(long native_region,
-                                                      Parcel p) {
-        // This is only called when sending a region through aidl, so really this should not
-        // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
-                null /*data*/);
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nativeEquals(long native_r1, long native_r2) {
-        Region_Delegate region1 = sManager.getDelegate(native_r1);
-        if (region1 == null) {
-            return false;
-        }
-
-        Region_Delegate region2 = sManager.getDelegate(native_r2);
-        if (region2 == null) {
-            return false;
-        }
-
-        return region1.mArea.equals(region2.mArea);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String nativeToString(long native_region) {
-        Region_Delegate region = sManager.getDelegate(native_region);
-        if (region == null) {
-            return "not found";
-        }
-
-        return region.mArea.toString();
-    }
-
-    // ---- Private delegate/helper methods ----
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
deleted file mode 100644
index 736f03e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.RectangularShape;
-import java.awt.geom.RoundRectangle2D;
-import java.util.EnumSet;
-import java.util.NoSuchElementException;
-
-/**
- * Defines a rectangle with rounded corners, where the sizes of the corners
- * are potentially different.
- */
-public class RoundRectangle extends RectangularShape {
-    public double x;
-    public double y;
-    public double width;
-    public double height;
-    public double ulWidth;
-    public double ulHeight;
-    public double urWidth;
-    public double urHeight;
-    public double lrWidth;
-    public double lrHeight;
-    public double llWidth;
-    public double llHeight;
-
-    private enum Zone {
-        CLOSE_OUTSIDE,
-        CLOSE_INSIDE,
-        MIDDLE,
-        FAR_INSIDE,
-        FAR_OUTSIDE
-    }
-
-    private final EnumSet<Zone> close = EnumSet.of(Zone.CLOSE_OUTSIDE, Zone.CLOSE_INSIDE);
-    private final EnumSet<Zone> far = EnumSet.of(Zone.FAR_OUTSIDE, Zone.FAR_INSIDE);
-
-    /**
-     * @param cornerDimensions array of 8 floating-point number corresponding to the width and
-     * the height of each corner in the following order: upper-left, upper-right, lower-right,
-     * lower-left. It assumes for the size the same convention as {@link RoundRectangle2D}, that
-     * is that the width and height of a corner correspond to the total width and height of the
-     * ellipse that corner is a quarter of.
-     */
-    public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
-        assert cornerDimensions.length == 8 : "The array of corner dimensions must have eight " +
-                    "elements";
-
-        this.x = x;
-        this.y = y;
-        this.width = width;
-        this.height = height;
-
-        float[] dimensions = cornerDimensions.clone();
-        // If a value is negative, the corresponding corner is squared
-        for (int i = 0; i < dimensions.length; i += 2) {
-            if (dimensions[i] < 0 || dimensions[i + 1] < 0) {
-                dimensions[i] = 0;
-                dimensions[i + 1] = 0;
-            }
-        }
-
-        double topCornerWidth = (dimensions[0] + dimensions[2]) / 2d;
-        double bottomCornerWidth = (dimensions[4] + dimensions[6]) / 2d;
-        double leftCornerHeight = (dimensions[1] + dimensions[7]) / 2d;
-        double rightCornerHeight = (dimensions[3] + dimensions[5]) / 2d;
-
-        // Rescale the corner dimensions if they are bigger than the rectangle
-        double scale = Math.min(1.0, width / topCornerWidth);
-        scale = Math.min(scale, width / bottomCornerWidth);
-        scale = Math.min(scale, height / leftCornerHeight);
-        scale = Math.min(scale, height / rightCornerHeight);
-
-        this.ulWidth = dimensions[0] * scale;
-        this.ulHeight = dimensions[1] * scale;
-        this.urWidth = dimensions[2] * scale;
-        this.urHeight = dimensions[3] * scale;
-        this.lrWidth = dimensions[4] * scale;
-        this.lrHeight = dimensions[5] * scale;
-        this.llWidth = dimensions[6] * scale;
-        this.llHeight = dimensions[7] * scale;
-    }
-
-    @Override
-    public double getX() {
-        return x;
-    }
-
-    @Override
-    public double getY() {
-        return y;
-    }
-
-    @Override
-    public double getWidth() {
-        return width;
-    }
-
-    @Override
-    public double getHeight() {
-        return height;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return (width <= 0d) || (height <= 0d);
-    }
-
-    @Override
-    public void setFrame(double x, double y, double w, double h) {
-        this.x = x;
-        this.y = y;
-        this.width = w;
-        this.height = h;
-    }
-
-    @Override
-    public Rectangle2D getBounds2D() {
-        return new Rectangle2D.Double(x, y, width, height);
-    }
-
-    @Override
-    public boolean contains(double x, double y) {
-        if (isEmpty()) {
-            return false;
-        }
-
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - point is outside bounding rectangle
-        if (x < x0 || y < y0 || x >= x1 || y >= y1) {
-            return false;
-        }
-
-        double insideTopX0 = x0 + ulWidth / 2d;
-        double insideLeftY0 = y0 + ulHeight / 2d;
-        if (x < insideTopX0 && y < insideLeftY0) {
-            // In the upper-left corner
-            return isInsideCorner(x - insideTopX0, y - insideLeftY0, ulWidth / 2d, ulHeight / 2d);
-        }
-
-        double insideTopX1 = x1 - urWidth / 2d;
-        double insideRightY0 = y0 + urHeight / 2d;
-        if (x > insideTopX1 && y < insideRightY0) {
-            // In the upper-right corner
-            return isInsideCorner(x - insideTopX1, y - insideRightY0, urWidth / 2d, urHeight / 2d);
-        }
-
-        double insideBottomX1 = x1 - lrWidth / 2d;
-        double insideRightY1 = y1 - lrHeight / 2d;
-        if (x > insideBottomX1 && y > insideRightY1) {
-            // In the lower-right corner
-            return isInsideCorner(x - insideBottomX1, y - insideRightY1, lrWidth / 2d,
-                    lrHeight / 2d);
-        }
-
-        double insideBottomX0 = x0 + llWidth / 2d;
-        double insideLeftY1 = y1 - llHeight / 2d;
-        if (x < insideBottomX0 && y > insideLeftY1) {
-            // In the lower-left corner
-            return isInsideCorner(x - insideBottomX0, y - insideLeftY1, llWidth / 2d,
-                    llHeight / 2d);
-        }
-
-        // In the central part of the rectangle
-        return true;
-    }
-
-    private boolean isInsideCorner(double x, double y, double width, double height) {
-        double squareDist = height * height * x * x + width * width * y * y;
-        return squareDist <= width * width * height * height;
-    }
-
-    private Zone classify(double coord, double side1, double arcSize1, double side2,
-            double arcSize2) {
-        if (coord < side1) {
-            return Zone.CLOSE_OUTSIDE;
-        } else if (coord < side1 + arcSize1) {
-            return Zone.CLOSE_INSIDE;
-        } else if (coord < side2 - arcSize2) {
-            return Zone.MIDDLE;
-        } else if (coord < side2) {
-            return Zone.FAR_INSIDE;
-        } else {
-            return Zone.FAR_OUTSIDE;
-        }
-    }
-
-    public boolean intersects(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        double x0 = getX();
-        double y0 = getY();
-        double x1 = x0 + getWidth();
-        double y1 = y0 + getHeight();
-        // Check for trivial rejection - bounding rectangles do not intersect
-        if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
-            return false;
-        }
-
-        double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
-        double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
-        double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
-        double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
-        Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
-        Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-        Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
-
-        // Trivially accept if any point is inside inner rectangle
-        if (x0class == Zone.MIDDLE || x1class == Zone.MIDDLE || y0class == Zone.MIDDLE || y1class == Zone.MIDDLE) {
-            return true;
-        }
-        // Trivially accept if either edge spans inner rectangle
-        if ((close.contains(x0class) && far.contains(x1class)) || (close.contains(y0class) &&
-                far.contains(y1class))) {
-            return true;
-        }
-
-        // Since neither edge spans the center, then one of the corners
-        // must be in one of the rounded edges.  We detect this case if
-        // a [xy]0class is 3 or a [xy]1class is 1.  One of those two cases
-        // must be true for each direction.
-        // We now find a "nearest point" to test for being inside a rounded
-        // corner.
-        if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
-            // Potentially in upper-left corner
-            x = x + w - x0 - ulWidth / 2d;
-            y = y + h - y0 - ulHeight / 2d;
-            return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
-        }
-        if (x1class == Zone.CLOSE_INSIDE) {
-            // Potentially in lower-left corner
-            x = x + w - x0 - llWidth / 2d;
-            y = y - y1 + llHeight / 2d;
-            return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
-        }
-        if (y1class == Zone.CLOSE_INSIDE) {
-            //Potentially in the upper-right corner
-            x = x - x1 + urWidth / 2d;
-            y = y + h - y0 - urHeight / 2d;
-            return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
-        }
-        // Potentially in the lower-right corner
-        x = x - x1 + lrWidth / 2d;
-        y = y - y1 + lrHeight / 2d;
-        return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
-    }
-
-    @Override
-    public boolean contains(double x, double y, double w, double h) {
-        if (isEmpty() || w <= 0 || h <= 0) {
-            return false;
-        }
-        return (contains(x, y) &&
-                contains(x + w, y) &&
-                contains(x, y + h) &&
-                contains(x + w, y + h));
-    }
-
-    @Override
-    public PathIterator getPathIterator(final AffineTransform at) {
-        return new PathIterator() {
-            int index;
-
-            // ArcIterator.btan(Math.PI/2)
-            public static final double CtrlVal = 0.5522847498307933;
-            private final double ncv = 1.0 - CtrlVal;
-
-            // Coordinates of control points for Bezier curves approximating the straight lines
-            // and corners of the rounded rectangle.
-            private final double[][] ctrlpts = {
-                    {0.0, 0.0, 0.0, ulHeight},
-                    {0.0, 0.0, 1.0, -llHeight},
-                    {0.0, 0.0, 1.0, -llHeight * ncv, 0.0, ncv * llWidth, 1.0, 0.0, 0.0, llWidth,
-                            1.0, 0.0},
-                    {1.0, -lrWidth, 1.0, 0.0},
-                    {1.0, -lrWidth * ncv, 1.0, 0.0, 1.0, 0.0, 1.0, -lrHeight * ncv, 1.0, 0.0, 1.0,
-                            -lrHeight},
-                    {1.0, 0.0, 0.0, urHeight},
-                    {1.0, 0.0, 0.0, ncv * urHeight, 1.0, -urWidth * ncv, 0.0, 0.0, 1.0, -urWidth,
-                            0.0, 0.0},
-                    {0.0, ulWidth, 0.0, 0.0},
-                    {0.0, ncv * ulWidth, 0.0, 0.0, 0.0, 0.0, 0.0, ncv * ulHeight, 0.0, 0.0, 0.0,
-                            ulHeight},
-                    {}
-            };
-            private final int[] types = {
-                    SEG_MOVETO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_LINETO, SEG_CUBICTO,
-                    SEG_CLOSE,
-            };
-
-            @Override
-            public int getWindingRule() {
-                return WIND_NON_ZERO;
-            }
-
-            @Override
-            public boolean isDone() {
-                return index >= ctrlpts.length;
-            }
-
-            @Override
-            public void next() {
-                index++;
-            }
-
-            @Override
-            public int currentSegment(float[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = (float) (x + ctrls[i] * width + ctrls[i + 1] / 2d);
-                    coords[nc++] = (float) (y + ctrls[i + 2] * height + ctrls[i + 3] / 2d);
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-
-            @Override
-            public int currentSegment(double[] coords) {
-                if (isDone()) {
-                    throw new NoSuchElementException("roundrect iterator out of bounds");
-                }
-                int nc = 0;
-                double ctrls[] = ctrlpts[index];
-                for (int i = 0; i < ctrls.length; i += 4) {
-                    coords[nc++] = x + ctrls[i] * width + ctrls[i + 1] / 2d;
-                    coords[nc++] = y + ctrls[i + 2] * height + ctrls[i + 3] / 2d;
-                }
-                if (at != null) {
-                    at.transform(coords, 0, coords, 0, nc / 2);
-                }
-                return types[index];
-            }
-        };
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
deleted file mode 100644
index 5b75089..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Shader.TileMode;
-
-/**
- * Delegate implementing the native methods of android.graphics.Shader
- *
- * Through the layoutlib_create tool, the original native methods of Shader have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Shader class.
- *
- * This also serve as a base class for all Shader delegate classes.
- *
- * @see DelegateManager
- *
- */
-public abstract class Shader_Delegate {
-
-    // ---- delegate manager ----
-    protected static final DelegateManager<Shader_Delegate> sManager =
-            new DelegateManager<Shader_Delegate>(Shader_Delegate.class);
-
-    // ---- delegate helper data ----
-
-    // ---- delegate data ----
-    private Matrix_Delegate mLocalMatrix = null;
-
-    // ---- Public Helper methods ----
-
-    public static Shader_Delegate getDelegate(long nativeShader) {
-        return sManager.getDelegate(nativeShader);
-    }
-
-    /**
-     * Returns the {@link TileMode} matching the given int.
-     * @param tileMode the tile mode int value
-     * @return the TileMode enum.
-     */
-    public static TileMode getTileMode(int tileMode) {
-        for (TileMode tm : TileMode.values()) {
-            if (tm.nativeInt == tileMode) {
-                return tm;
-            }
-        }
-
-        assert false;
-        return TileMode.CLAMP;
-    }
-
-    public abstract java.awt.Paint getJavaPaint();
-    public abstract boolean isSupported();
-    public abstract String getSupportMessage();
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSafeUnref(long nativeInstance) {
-        sManager.removeJavaReferenceFor(nativeInstance);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    protected Shader_Delegate(long nativeMatrix) {
-        mLocalMatrix = Matrix_Delegate.getDelegate(nativeMatrix);
-    }
-
-    protected java.awt.geom.AffineTransform getLocalMatrix() {
-        if (mLocalMatrix != null) {
-            return mLocalMatrix.getAffineTransform();
-        }
-
-        return new java.awt.geom.AffineTransform();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
deleted file mode 100644
index 6d2e9b4..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.awt.Stroke;
-
-/**
- * Delegate implementing the native methods of android.graphics.SumPathEffect
- *
- * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SumPathEffect class.
- *
- * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
- *
- * @see PathEffect_Delegate
- *
- */
-public class SumPathEffect_Delegate extends PathEffect_Delegate {
-
-    // ---- delegate data ----
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public Stroke getStroke(Paint_Delegate paint) {
-        // FIXME
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return false;
-    }
-
-    @Override
-    public String getSupportMessage() {
-        return "Sum Path Effects are not supported in Layout Preview mode.";
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate(long first, long second) {
-        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    // ---- Private delegate/helper methods ----
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
deleted file mode 100644
index 30152bc..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of android.graphics.SweepGradient
- *
- * Through the layoutlib_create tool, the original native methods of SweepGradient have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original SweepGradient class.
- *
- * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
- * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
- *
- * @see Shader_Delegate
- *
- */
-public class SweepGradient_Delegate extends Gradient_Delegate {
-
-    // ---- delegate data ----
-    private java.awt.Paint mJavaPaint;
-
-    // ---- Public Helper methods ----
-
-    @Override
-    public java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate1(long matrix, float x, float y, int colors[], float
-            positions[]) {
-        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(matrix, x, y, colors,
-                positions);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreate2(long matrix, float x, float y, int color0, int color1) {
-        return nativeCreate1(matrix, x, y, new int[] { color0, color1 },
-                null /*positions*/);
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param nativeMatrix reference to the shader's native transformation matrix
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    private SweepGradient_Delegate(long nativeMatrix, float cx, float cy,
-            int colors[], float positions[]) {
-        super(nativeMatrix, colors, positions);
-        mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
-    }
-
-    private class SweepGradientPaint extends GradientPaint {
-
-        private final float mCx;
-        private final float mCy;
-
-        public SweepGradientPaint(float cx, float cy, int[] colors,
-                float[] positions) {
-            super(colors, positions, null /*tileMode*/);
-            mCx = cx;
-            mCy = cy;
-        }
-
-        @Override
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-
-            java.awt.geom.AffineTransform canvasMatrix;
-            try {
-                canvasMatrix = xform.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                canvasMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
-            try {
-                localMatrix = localMatrix.createInverse();
-            } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
-                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
-                localMatrix = new java.awt.geom.AffineTransform();
-            }
-
-            return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
-        }
-
-        private class SweepGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.geom.AffineTransform mCanvasMatrix;
-            private final java.awt.geom.AffineTransform mLocalMatrix;
-            private final java.awt.image.ColorModel mColorModel;
-
-            public SweepGradientPaintContext(
-                    java.awt.geom.AffineTransform canvasMatrix,
-                    java.awt.geom.AffineTransform localMatrix,
-                    java.awt.image.ColorModel colorModel) {
-                mCanvasMatrix = canvasMatrix;
-                mLocalMatrix = localMatrix;
-                mColorModel = colorModel;
-            }
-
-            @Override
-            public void dispose() {
-            }
-
-            @Override
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            @Override
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
-                    mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
-                    mColorModel.isAlphaPremultiplied(), null);
-
-                int[] data = new int[w*h];
-
-                // compute angle from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                float[] pt1 = new float[2];
-                float[] pt2 = new float[2];
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        // handle the canvas transform
-                        pt1[0] = x + ix;
-                        pt1[1] = y + iy;
-                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        // handle the local matrix
-                        pt1[0] = pt2[0] - mCx;
-                        pt1[1] = pt2[1] - mCy;
-                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
-
-                        float dx = pt2[0];
-                        float dy = pt2[1];
-
-                        float angle;
-                        if (dx == 0) {
-                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
-                        } else if (dy == 0) {
-                            angle = (float) (dx < 0 ? Math.PI : 0);
-                        } else {
-                            angle = (float) Math.atan(dy / dx);
-                            if (dx > 0) {
-                                if (dy < 0) {
-                                    angle += Math.PI * 2;
-                                }
-                            } else {
-                                angle += Math.PI;
-                            }
-                        }
-
-                        // convert to 0-1. value and get color
-                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
deleted file mode 100644
index ce669cb..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.annotation.NonNull;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Typeface_Accessor {
-    public static boolean isSystemFont(@NonNull String fontName) {
-        return Typeface.sSystemFontMap.containsKey(fontName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
deleted file mode 100644
index fa311d0..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.FontFamily_Delegate.FontVariant;
-import android.graphics.fonts.FontVariationAxis;
-import android.text.FontConfig;
-
-import java.awt.Font;
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static android.graphics.FontFamily_Delegate.getFontLocation;
-
-/**
- * Delegate implementing the native methods of android.graphics.Typeface
- *
- * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original Typeface class.
- *
- * @see DelegateManager
- *
- */
-public final class Typeface_Delegate {
-
-    public static final String SYSTEM_FONTS = "/system/fonts/";
-
-    // ---- delegate manager ----
-    private static final DelegateManager<Typeface_Delegate> sManager =
-            new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
-
-
-    // ---- delegate data ----
-
-    @NonNull
-    private final FontFamily_Delegate[] mFontFamilies;  // the reference to FontFamily_Delegate.
-    /** @see Font#getStyle() */
-    private final int mStyle;
-    private final int mWeight;
-
-    private static long sDefaultTypeface;
-
-
-    // ---- Public Helper methods ----
-
-    public static Typeface_Delegate getDelegate(long nativeTypeface) {
-        return sManager.getDelegate(nativeTypeface);
-    }
-
-    /**
-     * Return a list of fonts that match the style and variant. The list is ordered according to
-     * preference of fonts.
-     *
-     * The list may contain null when the font failed to load. If null is reached when trying to
-     * render with this list of fonts, then a warning should be logged letting the user know that
-     * some font failed to load.
-     *
-     * @param variant The variant preferred. Can only be {@link FontVariant#COMPACT} or
-     *                {@link FontVariant#ELEGANT}
-     */
-    @NonNull
-    public List<Font> getFonts(FontVariant variant) {
-        assert variant != FontVariant.NONE;
-
-        // Calculate the required weight based on style and weight of this typeface.
-        int weight = mWeight + 50 +
-                ((mStyle & Font.BOLD) == 0 ? 0 : FontFamily_Delegate.BOLD_FONT_WEIGHT_DELTA);
-        if (weight > 1000) {
-            weight = 1000;
-        } else if (weight < 100) {
-            weight = 100;
-        }
-        final boolean isItalic = (mStyle & Font.ITALIC) != 0;
-        List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
-        for (int i = 0; i < mFontFamilies.length; i++) {
-            FontFamily_Delegate ffd = mFontFamilies[i];
-            if (ffd != null && ffd.isValid()) {
-                Font font = ffd.getFont(weight, isItalic);
-                if (font != null) {
-                    FontVariant ffdVariant = ffd.getVariant();
-                    if (ffdVariant == FontVariant.NONE) {
-                        fonts.add(font);
-                        continue;
-                    }
-                    // We cannot open each font and get locales supported, etc to match the fonts.
-                    // As a workaround, we hardcode certain assumptions like Elegant and Compact
-                    // always appear in pairs.
-                    assert i < mFontFamilies.length - 1;
-                    FontFamily_Delegate ffd2 = mFontFamilies[++i];
-                    assert ffd2 != null;
-                    FontVariant ffd2Variant = ffd2.getVariant();
-                    Font font2 = ffd2.getFont(weight, isItalic);
-                    assert ffd2Variant != FontVariant.NONE && ffd2Variant != ffdVariant
-                            && font2 != null;
-                    // Add the font with the matching variant to the list.
-                    if (variant == ffd.getVariant()) {
-                        fonts.add(font);
-                    } else {
-                        fonts.add(font2);
-                    }
-                } else {
-                    // The FontFamily is valid but doesn't contain any matching font. This means
-                    // that the font failed to load. We add null to the list of fonts. Don't throw
-                    // the warning just yet. If this is a non-english font, we don't want to warn
-                    // users who are trying to render only english text.
-                    fonts.add(null);
-                }
-            }
-        }
-        return fonts;
-    }
-
-    /**
-     * Clear the default typefaces when disposing bridge.
-     */
-    public static void resetDefaults() {
-        // Sometimes this is called before the Bridge is initialized. In that case, we don't want to
-        // initialize Typeface because the SDK fonts location hasn't been set.
-        if (FontFamily_Delegate.getFontLocation() != null) {
-            Typeface.sDefaults = null;
-        }
-    }
-
-
-    // ---- native methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypeface(long native_instance, int style) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-
-        return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style,
-                delegate.mWeight));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateFromTypefaceWithExactStyle(long native_instance,
-            int weight, boolean italic) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-
-        int style = weight >= 600 ? (italic ? Typeface.BOLD_ITALIC : Typeface.BOLD) :
-                (italic ? Typeface.ITALIC : Typeface.NORMAL);
-        return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style, weight));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromTypefaceWithVariation(long native_instance,
-            List<FontVariationAxis> axes) {
-        long newInstance = nativeCreateFromTypeface(native_instance, 0);
-
-        if (newInstance != 0) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                    "nativeCreateFromTypefaceWithVariation is not supported", null, null);
-        }
-        return newInstance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized int[] nativeGetSupportedAxes(long native_instance) {
-        // nativeCreateFromTypefaceWithVariation is not supported so we do not keep the axes
-        return null;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            delegate = sManager.getDelegate(sDefaultTypeface);
-        }
-        if (delegate == null) {
-            return 0;
-        }
-        Typeface_Delegate weightAlias =
-                new Typeface_Delegate(delegate.mFontFamilies, delegate.mStyle, weight);
-        return sManager.addNewDelegate(weightAlias);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized long nativeCreateFromArray(long[] familyArray, int weight,
-            int italic) {
-        FontFamily_Delegate[] fontFamilies = new FontFamily_Delegate[familyArray.length];
-        for (int i = 0; i < familyArray.length; i++) {
-            fontFamilies[i] = FontFamily_Delegate.getDelegate(familyArray[i]);
-        }
-        if (weight == Typeface.RESOLVE_BY_FONT_TABLE) {
-            weight = 400;
-        }
-        if (italic == Typeface.RESOLVE_BY_FONT_TABLE) {
-            italic = 0;
-        }
-        int style = weight >= 600 ? (italic == 1 ? Typeface.BOLD_ITALIC : Typeface.BOLD) :
-                (italic == 1 ? Typeface.ITALIC : Typeface.NORMAL);
-        Typeface_Delegate delegate = new Typeface_Delegate(fontFamilies, style, weight);
-        return sManager.addNewDelegate(delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeUnref(long native_instance) {
-        sManager.removeJavaReferenceFor(native_instance);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetStyle(long native_instance) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-
-        return delegate.mStyle;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nativeSetDefault(long native_instance) {
-        sDefaultTypeface = native_instance;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nativeGetBaseWeight(long native_instance) {
-        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
-        if (delegate == null) {
-            return 0;
-        }
-        return delegate.mWeight;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemFontConfigLocation() {
-        return new File(getFontLocation());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static FontFamily makeFamilyFromParsed(FontConfig.Family family,
-            Map<String, ByteBuffer> bufferForPath) {
-        FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
-        for (FontConfig.Font font : family.getFonts()) {
-            String fullPathName = "/system/fonts/" + font.getFontName();
-            FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
-                    font.getWeight(), font.isItalic());
-        }
-        fontFamily.freeze();
-        return fontFamily;
-    }
-
-    // ---- Private delegate/helper methods ----
-
-    public Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style, int weight) {
-        mFontFamilies = fontFamilies;
-        mStyle = style;
-        mWeight = weight;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
deleted file mode 100644
index ad2c564..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License") {}
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
-import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
-import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;
-
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * AnimatedVectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of AnimatedVectorDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class AnimatedVectorDrawable_Delegate {
-    private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new
-            DelegateManager<>(AnimatorSetHolder.class);
-    private static DelegateManager<PropertySetter> sHolders = new
-            DelegateManager<>(PropertySetter.class);
-
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateAnimatorSet() {
-        return sAnimatorSets.addNewDelegate(new AnimatorSetHolder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) {
-        // TODO: implement
-    }
-    @LayoutlibDelegate
-    /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
-            long nativeInterpolator, long startDelay, long duration, int repeatCount,
-            int repeatMode) {
-        PropertySetter holder = sHolders.getDelegate(propertyValuesHolder);
-        if (holder == null || holder.getValues() == null) {
-            return;
-        }
-
-        ObjectAnimator animator = new ObjectAnimator();
-        animator.setValues(holder.getValues());
-        animator.setInterpolator(
-                NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator));
-        animator.setStartDelay(startDelay);
-        animator.setDuration(duration);
-        animator.setRepeatCount(repeatCount);
-        animator.setRepeatMode(repeatMode);
-        animator.setTarget(holder);
-        animator.setPropertyName(holder.getValues().getPropertyName());
-
-        AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr);
-        assert set != null;
-        set.addAnimator(animator);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VGroup_Delegate group = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = group.getPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
-            long endValuePtr) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
-                "animations are not supported.", null, null);
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId,
-            int startValue, int endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Integer> setter = path.getIntPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId,
-            float startValue, float endValue) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
-        Consumer<Float> setter = path.getFloatPropertySetter(propertyId);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
-            float endValue) {
-        VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr);
-
-        return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha,
-                startValue,
-                endValue));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) {
-        PropertySetter setter = sHolders.getDelegate(nativePtr);
-        assert setter != null;
-
-        setter.setValues(data);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.start();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.reverse();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nEnd(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nReset(long animatorSetPtr) {
-        AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
-        assert animatorSet != null;
-
-        animatorSet.end();
-        animatorSet.start();
-    }
-
-    private static class AnimatorSetHolder {
-        private ArrayList<Animator> mAnimators = new ArrayList<>();
-        private AnimatorSet mAnimatorSet = null;
-
-        private void addAnimator(@NonNull Animator animator) {
-            mAnimators.add(animator);
-        }
-
-        private void ensureAnimatorSet() {
-            if (mAnimatorSet == null) {
-                mAnimatorSet = new AnimatorSet();
-                mAnimatorSet.playTogether(mAnimators);
-            }
-        }
-
-        private void start() {
-            ensureAnimatorSet();
-
-            mAnimatorSet.start();
-        }
-
-        private void end() {
-            mAnimatorSet.end();
-        }
-
-        private void reset() {
-            end();
-            start();
-        }
-
-        private void reverse() {
-            mAnimatorSet.reverse();
-        }
-    }
-
-    /**
-     * Class that allows setting a value and holds the range of values for the given property.
-     *
-     * @param <T> the type of the property
-     */
-    private static class PropertySetter<T> {
-        final Consumer<T> mValueSetter;
-        private PropertyValuesHolder mValues;
-
-        private PropertySetter(@NonNull Consumer<T> valueSetter) {
-            mValueSetter = valueSetter;
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setIntValue(Integer value) {
-        }
-
-        /**
-         * Method to set an {@link Integer} value for this property. The default implementation of
-         * this method doesn't do anything. This method is accessed via reflection by the
-         * PropertyValuesHolder.
-         */
-        public void setFloatValue(Float value) {
-        }
-
-        void setValues(float... values) {
-            mValues = PropertyValuesHolder.ofFloat("floatValue", values);
-        }
-
-        @Nullable
-        PropertyValuesHolder getValues() {
-            return mValues;
-        }
-
-        void setValues(int... values) {
-            mValues = PropertyValuesHolder.ofInt("intValue", values);
-        }
-    }
-
-    private static class IntPropertySetter extends PropertySetter<Integer> {
-        private IntPropertySetter(Consumer<Integer> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Integer> valueSetter, int... values) {
-            PropertySetter setter = new IntPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setIntValue(Integer value) {
-            mValueSetter.accept(value);
-        }
-    }
-
-    private static class FloatPropertySetter extends PropertySetter<Float> {
-        private FloatPropertySetter(Consumer<Float> valueSetter) {
-            super(valueSetter);
-        }
-
-        private static PropertySetter of(Consumer<Float> valueSetter, float... values) {
-            PropertySetter setter = new FloatPropertySetter(valueSetter);
-            setter.setValues(values);
-
-            return setter;
-        }
-
-        public void setFloatValue(Float value) {
-            mValueSetter.accept(value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
deleted file mode 100644
index fc848d9..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Canvas;
-import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
-
-public class AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate {
-    @LayoutlibDelegate
-    /*package*/ static boolean useLastSeenTarget(VectorDrawableAnimatorRT thisDrawableAnimator) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void onDraw(VectorDrawableAnimatorRT thisDrawableAnimator, Canvas canvas) {
-        // Do not attempt to record as we are not using a DisplayListCanvas
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
deleted file mode 100644
index a3ad2aac..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/GradientDrawable_Delegate.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.graphics.drawable.GradientDrawable.GradientState;
-
-import java.lang.reflect.Field;
-
-/**
- * Delegate implementing the native methods of {@link GradientDrawable}
- *
- * Through the layoutlib_create tool, the original native methods of GradientDrawable have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class GradientDrawable_Delegate {
-
-    /**
-     * The ring can be built either by drawing full circles, or by drawing arcs in case the
-     * circle isn't complete. LayoutLib cannot handle drawing full circles (requires path
-     * subtraction). So, if we need to draw full circles, we switch to drawing 99% circle.
-     */
-    @LayoutlibDelegate
-    /*package*/ static Path buildRing(GradientDrawable thisDrawable, GradientState st) {
-        boolean useLevel = st.mUseLevelForShape;
-        int level = thisDrawable.getLevel();
-        // 10000 is the max level. See android.graphics.drawable.Drawable#getLevel()
-        float sweep = useLevel ? (360.0f * level / 10000.0f) : 360f;
-        Field mLevel = null;
-        if (sweep >= 360 || sweep <= -360) {
-            st.mUseLevelForShape = true;
-            // Use reflection to set the value of the field to prevent setting the drawable to
-            // dirty again.
-            try {
-                mLevel = Drawable.class.getDeclaredField("mLevel");
-                mLevel.setAccessible(true);
-                mLevel.setInt(thisDrawable, 9999);  // set to one less than max.
-            } catch (NoSuchFieldException e) {
-                // The field has been removed in a recent framework change. Fall back to old
-                // buggy behaviour.
-            } catch (IllegalAccessException e) {
-                // We've already set the field to be accessible.
-                assert false;
-            }
-        }
-        Path path = thisDrawable.buildRing_Original(st);
-        st.mUseLevelForShape = useLevel;
-        if (mLevel != null) {
-            try {
-                mLevel.setInt(thisDrawable, level);
-            } catch (IllegalAccessException e) {
-                assert false;
-            }
-        }
-        return path;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
deleted file mode 100644
index 616784c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ /dev/null
@@ -1,1262 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics.drawable;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.TypedArray;
-import android.graphics.BaseCanvas_Delegate;
-import android.graphics.Canvas_Delegate;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Paint.Cap;
-import android.graphics.Paint.Join;
-import android.graphics.Paint_Delegate;
-import android.graphics.Path;
-import android.graphics.PathMeasure;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.MathUtils;
-import android.util.PathParser_Delegate;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-import static android.graphics.Canvas.CLIP_SAVE_FLAG;
-import static android.graphics.Canvas.MATRIX_SAVE_FLAG;
-import static android.graphics.Paint.Cap.BUTT;
-import static android.graphics.Paint.Cap.ROUND;
-import static android.graphics.Paint.Cap.SQUARE;
-import static android.graphics.Paint.Join.BEVEL;
-import static android.graphics.Paint.Join.MITER;
-import static android.graphics.Paint.Style;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link VectorDrawable}
- * <p>
- * Through the layoutlib_create tool, the original  methods of VectorDrawable have been replaced by
- * calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class VectorDrawable_Delegate {
-    private static final String LOGTAG = VectorDrawable_Delegate.class.getSimpleName();
-    private static final boolean DBG_VECTOR_DRAWABLE = false;
-
-    private static final DelegateManager<VNativeObject> sPathManager =
-            new DelegateManager<>(VNativeObject.class);
-
-    private static long addNativeObject(VNativeObject object) {
-        long ptr = sPathManager.addNewDelegate(object);
-        object.setNativePtr(ptr);
-
-        return ptr;
-    }
-
-    /**
-     * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is
-     * null.
-     */
-    private static TypedArray obtainAttributes(
-            Resources res, Theme theme, AttributeSet set, int[] attrs) {
-        if (theme == null) {
-            return res.obtainAttributes(set, attrs);
-        }
-        return theme.obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    private static int applyAlpha(int color, float alpha) {
-        int alphaBytes = Color.alpha(color);
-        color &= 0x00FFFFFF;
-        color |= ((int) (alphaBytes * alpha)) << 24;
-        return color;
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTree(long rootGroupPtr) {
-        return addNativeObject(new VPathRenderer_Delegate(rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) {
-        VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr);
-        return addNativeObject(new VPathRenderer_Delegate(rendererToCopy,
-                rootGroupPtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
-            float viewportHeight) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.mViewportWidth = viewportWidth;
-        nativePathRenderer.mViewportHeight = viewportHeight;
-    }
-
-    @LayoutlibDelegate
-    static boolean nSetRootAlpha(long rendererPtr, float alpha) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-        nativePathRenderer.setRootAlpha(alpha);
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static float nGetRootAlpha(long rendererPtr) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        return nativePathRenderer.getRootAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetAllowCaching(long rendererPtr, boolean allowCaching) {
-        // ignored
-    }
-
-    @LayoutlibDelegate
-    static int nDraw(long rendererPtr, long canvasWrapperPtr,
-            long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) {
-        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
-
-        Canvas_Delegate.nSave(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-        Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.left, bounds.top);
-
-        if (needsMirroring) {
-            Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.width(), 0);
-            Canvas_Delegate.nScale(canvasWrapperPtr, -1.0f, 1.0f);
-        }
-
-        // At this point, canvas has been translated to the right position.
-        // And we use this bound for the destination rect for the drawBitmap, so
-        // we offset to (0, 0);
-        bounds.offsetTo(0, 0);
-        nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
-
-        Canvas_Delegate.nRestore(canvasWrapperPtr);
-
-        return bounds.width() * bounds.height();
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath() {
-        return addNativeObject(new VFullPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateFullPath(long nativeFullPathPtr) {
-        VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
-        return addNativeObject(new VFullPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData,
-            int length) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        ByteBuffer properties = ByteBuffer.wrap(propertiesData);
-        properties.order(ByteOrder.nativeOrder());
-
-        properties.putFloat(VFullPath_Delegate.STROKE_WIDTH_INDEX * 4, path.getStrokeWidth());
-        properties.putInt(VFullPath_Delegate.STROKE_COLOR_INDEX * 4, path.getStrokeColor());
-        properties.putFloat(VFullPath_Delegate.STROKE_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putInt(VFullPath_Delegate.FILL_COLOR_INDEX * 4, path.getFillColor());
-        properties.putFloat(VFullPath_Delegate.FILL_ALPHA_INDEX * 4, path.getStrokeAlpha());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_START_INDEX * 4, path.getTrimPathStart());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_END_INDEX * 4, path.getTrimPathEnd());
-        properties.putFloat(VFullPath_Delegate.TRIM_PATH_OFFSET_INDEX * 4,
-                path.getTrimPathOffset());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_CAP_INDEX * 4, path.getStrokeLineCap());
-        properties.putInt(VFullPath_Delegate.STROKE_LINE_JOIN_INDEX * 4, path.getStrokeLineJoin());
-        properties.putFloat(VFullPath_Delegate.STROKE_MITER_LIMIT_INDEX * 4,
-                path.getStrokeMiterlimit());
-        properties.putInt(VFullPath_Delegate.FILL_TYPE_INDEX * 4, path.getFillType());
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
-            int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
-            float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
-            int strokeLineJoin, int fillType) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeWidth(strokeWidth);
-        path.setStrokeColor(strokeColor);
-        path.setStrokeAlpha(strokeAlpha);
-        path.setFillColor(fillColor);
-        path.setFillAlpha(fillAlpha);
-        path.setTrimPathStart(trimPathStart);
-        path.setTrimPathEnd(trimPathEnd);
-        path.setTrimPathOffset(trimPathOffset);
-        path.setStrokeMiterlimit(strokeMiterLimit);
-        path.setStrokeLineCap(strokeLineCap);
-        path.setStrokeLineJoin(strokeLineJoin);
-        path.setFillType(fillType);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setFillGradient(fillGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-
-        path.setStrokeGradient(strokeGradientPtr);
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath() {
-        return addNativeObject(new VClipPath_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateClipPath(long clipPathPtr) {
-        VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr);
-        return addNativeObject(new VClipPath_Delegate(original));
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup() {
-        return addNativeObject(new VGroup_Delegate());
-    }
-
-    @LayoutlibDelegate
-    static long nCreateGroup(long groupPtr) {
-        VGroup_Delegate original = VNativeObject.getDelegate(groupPtr);
-        return addNativeObject(new VGroup_Delegate(original, new ArrayMap<>()));
-    }
-
-    @LayoutlibDelegate
-    static void nSetName(long nodePtr, String name) {
-        VNativeObject group = VNativeObject.getDelegate(nodePtr);
-        group.setName(name);
-    }
-
-    @LayoutlibDelegate
-    static boolean nGetGroupProperties(long groupPtr, float[] propertiesData,
-            int length) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        FloatBuffer properties = FloatBuffer.wrap(propertiesData);
-
-        properties.put(VGroup_Delegate.ROTATE_INDEX, group.getRotation());
-        properties.put(VGroup_Delegate.PIVOT_X_INDEX, group.getPivotX());
-        properties.put(VGroup_Delegate.PIVOT_Y_INDEX, group.getPivotY());
-        properties.put(VGroup_Delegate.SCALE_X_INDEX, group.getScaleX());
-        properties.put(VGroup_Delegate.SCALE_Y_INDEX, group.getScaleY());
-        properties.put(VGroup_Delegate.TRANSLATE_X_INDEX, group.getTranslateX());
-        properties.put(VGroup_Delegate.TRANSLATE_Y_INDEX, group.getTranslateY());
-
-        return true;
-    }
-    @LayoutlibDelegate
-    static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
-            float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-
-        group.setRotation(rotate);
-        group.setPivotX(pivotX);
-        group.setPivotY(pivotY);
-        group.setScaleX(scaleX);
-        group.setScaleY(scaleY);
-        group.setTranslateX(translateX);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nAddChild(long groupPtr, long nodePtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.mChildren.add(VNativeObject.getDelegate(nodePtr));
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathString(long pathPtr, String pathString, int length) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString));
-    }
-
-    /**
-     * The setters and getters below for paths and groups are here temporarily, and will be removed
-     * once the animation in AVD is replaced with RenderNodeAnimator, in which case the animation
-     * will modify these properties in native. By then no JNI hopping would be necessary for VD
-     * during animation, and these setters and getters will be obsolete.
-     */
-    // Setters and getters during animation.
-    @LayoutlibDelegate
-    static float nGetRotation(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getRotation();
-    }
-
-    @LayoutlibDelegate
-    static void nSetRotation(long groupPtr, float rotation) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setRotation(rotation);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotX(long groupPtr, float pivotX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotX(pivotX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetPivotY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getPivotY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetPivotY(long groupPtr, float pivotY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setPivotY(pivotY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleX(long groupPtr, float scaleX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleX(scaleX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetScaleY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getScaleY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetScaleY(long groupPtr, float scaleY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setScaleY(scaleY);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateX(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateX();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateX(long groupPtr, float translateX) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateX(translateX);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTranslateY(long groupPtr) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        return group.getTranslateY();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTranslateY(long groupPtr, float translateY) {
-        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
-        group.setTranslateY(translateY);
-    }
-
-    @LayoutlibDelegate
-    static void nSetPathData(long pathPtr, long pathDataPtr) {
-        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeWidth(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeWidth();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeWidth(long pathPtr, float width) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeWidth(width);
-    }
-
-    @LayoutlibDelegate
-    static int nGetStrokeColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeColor(long pathPtr, int strokeColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeColor(strokeColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetStrokeAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getStrokeAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetStrokeAlpha(long pathPtr, float alpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setStrokeAlpha(alpha);
-    }
-
-    @LayoutlibDelegate
-    static int nGetFillColor(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillColor();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillColor(long pathPtr, int fillColor) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillColor(fillColor);
-    }
-
-    @LayoutlibDelegate
-    static float nGetFillAlpha(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getFillAlpha();
-    }
-
-    @LayoutlibDelegate
-    static void nSetFillAlpha(long pathPtr, float fillAlpha) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setFillAlpha(fillAlpha);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathStart(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathStart();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathStart(long pathPtr, float trimPathStart) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathStart(trimPathStart);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathEnd(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathEnd();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathEnd(trimPathEnd);
-    }
-
-    @LayoutlibDelegate
-    static float nGetTrimPathOffset(long pathPtr) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        return path.getTrimPathOffset();
-    }
-
-    @LayoutlibDelegate
-    static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) {
-        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
-        path.setTrimPathOffset(trimPathOffset);
-    }
-
-    /**
-     * Base class for all the internal Delegates that does two functions:
-     * <ol>
-     *     <li>Serves as base class to store all the delegates in one {@link DelegateManager}
-     *     <li>Provides setName for all the classes. {@link VPathRenderer_Delegate} does actually
-     *     not need it
-     * </ol>
-     */
-    abstract static class VNativeObject {
-        long mNativePtr = 0;
-
-        @NonNull
-        static <T> T getDelegate(long nativePtr) {
-            //noinspection unchecked
-            T vNativeObject = (T) sPathManager.getDelegate(nativePtr);
-
-            assert vNativeObject != null;
-            return vNativeObject;
-        }
-
-        abstract void setName(String name);
-
-        void setNativePtr(long nativePtr) {
-            mNativePtr = nativePtr;
-        }
-
-        /**
-         * Method to explicitly dispose native objects
-         */
-        void dispose() {
-        }
-    }
-
-    private static class VClipPath_Delegate extends VPath_Delegate {
-        private VClipPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VClipPath_Delegate(VClipPath_Delegate copy) {
-            super(copy);
-        }
-
-        @Override
-        public boolean isClipPath() {
-            return true;
-        }
-    }
-
-    static class VFullPath_Delegate extends VPath_Delegate {
-        // These constants need to be kept in sync with their values in VectorDrawable.VFullPath
-        private static final int STROKE_WIDTH_INDEX = 0;
-        private static final int STROKE_COLOR_INDEX = 1;
-        private static final int STROKE_ALPHA_INDEX = 2;
-        private static final int FILL_COLOR_INDEX = 3;
-        private static final int FILL_ALPHA_INDEX = 4;
-        private static final int TRIM_PATH_START_INDEX = 5;
-        private static final int TRIM_PATH_END_INDEX = 6;
-        private static final int TRIM_PATH_OFFSET_INDEX = 7;
-        private static final int STROKE_LINE_CAP_INDEX = 8;
-        private static final int STROKE_LINE_JOIN_INDEX = 9;
-        private static final int STROKE_MITER_LIMIT_INDEX = 10;
-        private static final int FILL_TYPE_INDEX = 11;
-
-        private static final int LINECAP_BUTT = 0;
-        private static final int LINECAP_ROUND = 1;
-        private static final int LINECAP_SQUARE = 2;
-
-        private static final int LINEJOIN_MITER = 0;
-        private static final int LINEJOIN_ROUND = 1;
-        private static final int LINEJOIN_BEVEL = 2;
-
-        @NonNull
-        public Consumer<Float> getFloatPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_WIDTH_INDEX:
-                    return this::setStrokeWidth;
-                case STROKE_ALPHA_INDEX:
-                    return this::setStrokeAlpha;
-                case FILL_ALPHA_INDEX:
-                    return this::setFillAlpha;
-                case TRIM_PATH_START_INDEX:
-                    return this::setTrimPathStart;
-                case TRIM_PATH_END_INDEX:
-                    return this::setTrimPathEnd;
-                case TRIM_PATH_OFFSET_INDEX:
-                    return this::setTrimPathOffset;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        @NonNull
-        public Consumer<Integer> getIntPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case STROKE_COLOR_INDEX:
-                    return this::setStrokeColor;
-                case FILL_COLOR_INDEX:
-                    return this::setFillColor;
-            }
-
-            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-
-        int mStrokeColor = Color.TRANSPARENT;
-        float mStrokeWidth = 0;
-
-        int mFillColor = Color.TRANSPARENT;
-        long mStrokeGradient = 0;
-        long mFillGradient = 0;
-        float mStrokeAlpha = 1.0f;
-        float mFillAlpha = 1.0f;
-        float mTrimPathStart = 0;
-        float mTrimPathEnd = 1;
-        float mTrimPathOffset = 0;
-
-        Cap mStrokeLineCap = BUTT;
-        Join mStrokeLineJoin = MITER;
-        float mStrokeMiterlimit = 4;
-
-        int mFillType = 0; // WINDING(0) is the default value. See Path.FillType
-
-        private VFullPath_Delegate() {
-            // Empty constructor.
-        }
-
-        private VFullPath_Delegate(VFullPath_Delegate copy) {
-            super(copy);
-
-            mStrokeColor = copy.mStrokeColor;
-            mStrokeWidth = copy.mStrokeWidth;
-            mStrokeAlpha = copy.mStrokeAlpha;
-            mFillColor = copy.mFillColor;
-            mFillAlpha = copy.mFillAlpha;
-            mTrimPathStart = copy.mTrimPathStart;
-            mTrimPathEnd = copy.mTrimPathEnd;
-            mTrimPathOffset = copy.mTrimPathOffset;
-
-            mStrokeLineCap = copy.mStrokeLineCap;
-            mStrokeLineJoin = copy.mStrokeLineJoin;
-            mStrokeMiterlimit = copy.mStrokeMiterlimit;
-
-            mStrokeGradient = copy.mStrokeGradient;
-            mFillGradient = copy.mFillGradient;
-            mFillType = copy.mFillType;
-        }
-
-        private int getStrokeLineCap() {
-            switch (mStrokeLineCap) {
-                case BUTT:
-                    return LINECAP_BUTT;
-                case ROUND:
-                    return LINECAP_ROUND;
-                case SQUARE:
-                    return LINECAP_SQUARE;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineCap(int cap) {
-            switch (cap) {
-                case LINECAP_BUTT:
-                    mStrokeLineCap = BUTT;
-                    break;
-                case LINECAP_ROUND:
-                    mStrokeLineCap = ROUND;
-                    break;
-                case LINECAP_SQUARE:
-                    mStrokeLineCap = SQUARE;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeLineJoin() {
-            switch (mStrokeLineJoin) {
-                case MITER:
-                    return LINEJOIN_MITER;
-                case ROUND:
-                    return LINEJOIN_ROUND;
-                case BEVEL:
-                    return LINEJOIN_BEVEL;
-                default:
-                    assert false;
-            }
-
-            return -1;
-        }
-
-        private void setStrokeLineJoin(int join) {
-            switch (join) {
-                case LINEJOIN_BEVEL:
-                    mStrokeLineJoin = BEVEL;
-                    break;
-                case LINEJOIN_MITER:
-                    mStrokeLineJoin = MITER;
-                    break;
-                case LINEJOIN_ROUND:
-                    mStrokeLineJoin = Join.ROUND;
-                    break;
-                default:
-                    assert false;
-            }
-        }
-
-        private int getStrokeColor() {
-            return mStrokeColor;
-        }
-
-        private void setStrokeColor(int strokeColor) {
-            mStrokeColor = strokeColor;
-        }
-
-        private float getStrokeWidth() {
-            return mStrokeWidth;
-        }
-
-        private void setStrokeWidth(float strokeWidth) {
-            mStrokeWidth = strokeWidth;
-        }
-
-        private float getStrokeAlpha() {
-            return mStrokeAlpha;
-        }
-
-        private void setStrokeAlpha(float strokeAlpha) {
-            mStrokeAlpha = strokeAlpha;
-        }
-
-        private int getFillColor() {
-            return mFillColor;
-        }
-
-        private void setFillColor(int fillColor) {
-            mFillColor = fillColor;
-        }
-
-        private float getFillAlpha() {
-            return mFillAlpha;
-        }
-
-        private void setFillAlpha(float fillAlpha) {
-            mFillAlpha = fillAlpha;
-        }
-
-        private float getTrimPathStart() {
-            return mTrimPathStart;
-        }
-
-        private void setTrimPathStart(float trimPathStart) {
-            mTrimPathStart = trimPathStart;
-        }
-
-        private float getTrimPathEnd() {
-            return mTrimPathEnd;
-        }
-
-        private void setTrimPathEnd(float trimPathEnd) {
-            mTrimPathEnd = trimPathEnd;
-        }
-
-        private float getTrimPathOffset() {
-            return mTrimPathOffset;
-        }
-
-        private void setTrimPathOffset(float trimPathOffset) {
-            mTrimPathOffset = trimPathOffset;
-        }
-
-        private void setStrokeMiterlimit(float limit) {
-            mStrokeMiterlimit = limit;
-        }
-
-        private float getStrokeMiterlimit() {
-            return mStrokeMiterlimit;
-        }
-
-        private void setStrokeGradient(long gradientPtr) {
-            mStrokeGradient = gradientPtr;
-        }
-
-        private void setFillGradient(long gradientPtr) {
-            mFillGradient = gradientPtr;
-        }
-
-        private void setFillType(int fillType) {
-            mFillType = fillType;
-        }
-
-        private int getFillType() {
-            return mFillType;
-        }
-    }
-
-    static class VGroup_Delegate extends VNativeObject {
-        // This constants need to be kept in sync with their definitions in VectorDrawable.Group
-        private static final int ROTATE_INDEX = 0;
-        private static final int PIVOT_X_INDEX = 1;
-        private static final int PIVOT_Y_INDEX = 2;
-        private static final int SCALE_X_INDEX = 3;
-        private static final int SCALE_Y_INDEX = 4;
-        private static final int TRANSLATE_X_INDEX = 5;
-        private static final int TRANSLATE_Y_INDEX = 6;
-
-        public Consumer<Float> getPropertySetter(int propertyIdx) {
-            switch (propertyIdx) {
-                case ROTATE_INDEX:
-                    return this::setRotation;
-                case PIVOT_X_INDEX:
-                    return this::setPivotX;
-                case PIVOT_Y_INDEX:
-                    return this::setPivotY;
-                case SCALE_X_INDEX:
-                    return this::setScaleX;
-                case SCALE_Y_INDEX:
-                    return this::setScaleY;
-                case TRANSLATE_X_INDEX:
-                    return this::setTranslateX;
-                case TRANSLATE_Y_INDEX:
-                    return this::setTranslateY;
-            }
-
-            assert false : ("Invalid VGroup_Delegate property index " + propertyIdx);
-            return t -> {};
-        }
-
-        /////////////////////////////////////////////////////
-        // Variables below need to be copied (deep copy if applicable) for mutation.
-        final ArrayList<Object> mChildren = new ArrayList<>();
-        // mStackedMatrix is only used temporarily when drawing, it combines all
-        // the parents' local matrices with the current one.
-        private final Matrix mStackedMatrix = new Matrix();
-        // mLocalMatrix is updated based on the update of transformation information,
-        // either parsed from the XML or by animation.
-        private final Matrix mLocalMatrix = new Matrix();
-        private float mRotate = 0;
-        private float mPivotX = 0;
-        private float mPivotY = 0;
-        private float mScaleX = 1;
-        private float mScaleY = 1;
-        private float mTranslateX = 0;
-        private float mTranslateY = 0;
-        private int mChangingConfigurations;
-        private String mGroupName = null;
-
-        private VGroup_Delegate(VGroup_Delegate copy, ArrayMap<String, Object> targetsMap) {
-            mRotate = copy.mRotate;
-            mPivotX = copy.mPivotX;
-            mPivotY = copy.mPivotY;
-            mScaleX = copy.mScaleX;
-            mScaleY = copy.mScaleY;
-            mTranslateX = copy.mTranslateX;
-            mTranslateY = copy.mTranslateY;
-            mGroupName = copy.mGroupName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            if (mGroupName != null) {
-                targetsMap.put(mGroupName, this);
-            }
-
-            mLocalMatrix.set(copy.mLocalMatrix);
-        }
-
-        private VGroup_Delegate() {
-        }
-
-        private void updateLocalMatrix() {
-            // The order we apply is the same as the
-            // RenderNode.cpp::applyViewPropertyTransforms().
-            mLocalMatrix.reset();
-            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
-            mLocalMatrix.postScale(mScaleX, mScaleY);
-            mLocalMatrix.postRotate(mRotate, 0, 0);
-            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
-        }
-
-        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
-        private float getRotation() {
-            return mRotate;
-        }
-
-        private void setRotation(float rotation) {
-            if (rotation != mRotate) {
-                mRotate = rotation;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotX() {
-            return mPivotX;
-        }
-
-        private void setPivotX(float pivotX) {
-            if (pivotX != mPivotX) {
-                mPivotX = pivotX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getPivotY() {
-            return mPivotY;
-        }
-
-        private void setPivotY(float pivotY) {
-            if (pivotY != mPivotY) {
-                mPivotY = pivotY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleX() {
-            return mScaleX;
-        }
-
-        private void setScaleX(float scaleX) {
-            if (scaleX != mScaleX) {
-                mScaleX = scaleX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getScaleY() {
-            return mScaleY;
-        }
-
-        private void setScaleY(float scaleY) {
-            if (scaleY != mScaleY) {
-                mScaleY = scaleY;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateX() {
-            return mTranslateX;
-        }
-
-        private void setTranslateX(float translateX) {
-            if (translateX != mTranslateX) {
-                mTranslateX = translateX;
-                updateLocalMatrix();
-            }
-        }
-
-        private float getTranslateY() {
-            return mTranslateY;
-        }
-
-        private void setTranslateY(float translateY) {
-            if (translateY != mTranslateY) {
-                mTranslateY = translateY;
-                updateLocalMatrix();
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mGroupName = name;
-        }
-
-        @Override
-        protected void dispose() {
-            mChildren.stream().filter(child -> child instanceof VNativeObject).forEach(child
-                    -> {
-                VNativeObject nativeObject = (VNativeObject) child;
-                if (nativeObject.mNativePtr != 0) {
-                    sPathManager.removeJavaReferenceFor(nativeObject.mNativePtr);
-                    nativeObject.mNativePtr = 0;
-                }
-                nativeObject.dispose();
-            });
-            mChildren.clear();
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            super.finalize();
-        }
-    }
-
-    public static class VPath_Delegate extends VNativeObject {
-        protected PathParser_Delegate.PathDataNode[] mNodes = null;
-        String mPathName;
-        int mChangingConfigurations;
-
-        public VPath_Delegate() {
-            // Empty constructor.
-        }
-
-        public VPath_Delegate(VPath_Delegate copy) {
-            mPathName = copy.mPathName;
-            mChangingConfigurations = copy.mChangingConfigurations;
-            mNodes = copy.mNodes != null ? PathParser_Delegate.deepCopyNodes(copy.mNodes) : null;
-        }
-
-        public void toPath(Path path) {
-            path.reset();
-            if (mNodes != null) {
-                PathParser_Delegate.PathDataNode.nodesToPath(mNodes,
-                        Path_Delegate.getDelegate(path.mNativePath));
-            }
-        }
-
-        @Override
-        public void setName(String name) {
-            mPathName = name;
-        }
-
-        public boolean isClipPath() {
-            return false;
-        }
-
-        private void setPathData(PathParser_Delegate.PathDataNode[] nodes) {
-            if (!PathParser_Delegate.canMorph(mNodes, nodes)) {
-                // This should not happen in the middle of animation.
-                mNodes = PathParser_Delegate.deepCopyNodes(nodes);
-            } else {
-                PathParser_Delegate.updateNodes(mNodes, nodes);
-            }
-        }
-
-        @Override
-        void dispose() {
-            mNodes = null;
-        }
-    }
-
-    static class VPathRenderer_Delegate extends VNativeObject {
-        /* Right now the internal data structure is organized as a tree.
-         * Each node can be a group node, or a path.
-         * A group node can have groups or paths as children, but a path node has
-         * no children.
-         * One example can be:
-         *                 Root Group
-         *                /    |     \
-         *           Group    Path    Group
-         *          /     \             |
-         *         Path   Path         Path
-         *
-         */
-        // Variables that only used temporarily inside the draw() call, so there
-        // is no need for deep copying.
-        private final Path mPath;
-        private final Path mRenderPath;
-        private final Matrix mFinalPathMatrix = new Matrix();
-        private final long mRootGroupPtr;
-        private float mViewportWidth = 0;
-        private float mViewportHeight = 0;
-        private float mRootAlpha = 1.0f;
-        private Paint mStrokePaint;
-        private Paint mFillPaint;
-        private PathMeasure mPathMeasure;
-
-        private VPathRenderer_Delegate(long rootGroupPtr) {
-            mRootGroupPtr = rootGroupPtr;
-            mPath = new Path();
-            mRenderPath = new Path();
-        }
-
-        private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy,
-                long rootGroupPtr) {
-            this(rootGroupPtr);
-            mViewportWidth = rendererToCopy.mViewportWidth;
-            mViewportHeight = rendererToCopy.mViewportHeight;
-            mRootAlpha = rendererToCopy.mRootAlpha;
-        }
-
-        private float getRootAlpha() {
-            return mRootAlpha;
-        }
-
-        void setRootAlpha(float alpha) {
-            mRootAlpha = alpha;
-        }
-
-        private void drawGroupTree(VGroup_Delegate currentGroup, Matrix currentMatrix,
-                long canvasPtr, int w, int h, long filterPtr) {
-            // Calculate current group's matrix by preConcat the parent's and
-            // and the current one on the top of the stack.
-            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
-            // Mi the local matrix at level i of the group tree.
-            currentGroup.mStackedMatrix.set(currentMatrix);
-            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
-
-            // Save the current clip information, which is local to this group.
-            Canvas_Delegate.nSave(canvasPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
-            // Draw the group tree in the same order as the XML file.
-            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
-                Object child = currentGroup.mChildren.get(i);
-                if (child instanceof VGroup_Delegate) {
-                    VGroup_Delegate childGroup = (VGroup_Delegate) child;
-                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
-                            canvasPtr, w, h, filterPtr);
-                } else if (child instanceof VPath_Delegate) {
-                    VPath_Delegate childPath = (VPath_Delegate) child;
-                    drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
-                }
-            }
-            Canvas_Delegate.nRestore(canvasPtr);
-        }
-
-        public void draw(long canvasPtr, long filterPtr, int w, int h) {
-            // Traverse the tree in pre-order to draw.
-            drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
-        }
-
-        private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
-                int w,
-                int h,
-                long filterPtr) {
-            final float scaleX = w / mViewportWidth;
-            final float scaleY = h / mViewportHeight;
-            final float minScale = Math.min(scaleX, scaleY);
-            final Matrix groupStackedMatrix = VGroup.mStackedMatrix;
-
-            mFinalPathMatrix.set(groupStackedMatrix);
-            mFinalPathMatrix.postScale(scaleX, scaleY);
-
-            final float matrixScale = getMatrixScale(groupStackedMatrix);
-            if (matrixScale == 0) {
-                // When either x or y is scaled to 0, we don't need to draw anything.
-                return;
-            }
-            VPath.toPath(mPath);
-            final Path path = mPath;
-
-            mRenderPath.reset();
-
-            if (VPath.isClipPath()) {
-                mRenderPath.addPath(path, mFinalPathMatrix);
-                Canvas_Delegate.nClipPath(canvasPtr, mRenderPath.mNativePath, Op
-                        .INTERSECT.nativeInt);
-            } else {
-                VFullPath_Delegate fullPath = (VFullPath_Delegate) VPath;
-                if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
-                    float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
-                    float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
-
-                    if (mPathMeasure == null) {
-                        mPathMeasure = new PathMeasure();
-                    }
-                    mPathMeasure.setPath(mPath, false);
-
-                    float len = mPathMeasure.getLength();
-                    start = start * len;
-                    end = end * len;
-                    path.reset();
-                    if (start > end) {
-                        mPathMeasure.getSegment(start, len, path, true);
-                        mPathMeasure.getSegment(0f, end, path, true);
-                    } else {
-                        mPathMeasure.getSegment(start, end, path, true);
-                    }
-                    path.rLineTo(0, 0); // fix bug in measure
-                }
-                mRenderPath.addPath(path, mFinalPathMatrix);
-
-                if (fullPath.mFillColor != Color.TRANSPARENT) {
-                    if (mFillPaint == null) {
-                        mFillPaint = new Paint();
-                        mFillPaint.setStyle(Style.FILL);
-                        mFillPaint.setAntiAlias(true);
-                    }
-
-                    final Paint fillPaint = mFillPaint;
-                    fillPaint.setColor(applyAlpha(applyAlpha(fullPath.mFillColor, fullPath
-                      .mFillAlpha), getRootAlpha()));
-                    Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
-                            .getNativeInstance());
-                    // mFillPaint can not be null at this point so we will have a delegate
-                    assert fillPaintDelegate != null;
-                    fillPaintDelegate.setColorFilter(filterPtr);
-                    fillPaintDelegate.setShader(fullPath.mFillGradient);
-                    Path_Delegate.nSetFillType(mRenderPath.mNativePath, fullPath.mFillType);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
-                            .getNativeInstance());
-                }
-
-                if (fullPath.mStrokeColor != Color.TRANSPARENT) {
-                    if (mStrokePaint == null) {
-                        mStrokePaint = new Paint();
-                        mStrokePaint.setStyle(Style.STROKE);
-                        mStrokePaint.setAntiAlias(true);
-                    }
-
-                    final Paint strokePaint = mStrokePaint;
-                    if (fullPath.mStrokeLineJoin != null) {
-                        strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
-                    }
-
-                    if (fullPath.mStrokeLineCap != null) {
-                        strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
-                    }
-
-                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
-                    strokePaint.setColor(applyAlpha(applyAlpha(fullPath.mStrokeColor, fullPath
-                      .mStrokeAlpha), getRootAlpha()));
-                    Paint_Delegate strokePaintDelegate = Paint_Delegate.getDelegate(strokePaint
-                            .getNativeInstance());
-                    // mStrokePaint can not be null at this point so we will have a delegate
-                    assert strokePaintDelegate != null;
-                    strokePaintDelegate.setColorFilter(filterPtr);
-                    final float finalStrokeScale = minScale * matrixScale;
-                    strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
-                    strokePaintDelegate.setShader(fullPath.mStrokeGradient);
-                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
-                            .getNativeInstance());
-                }
-            }
-        }
-
-        private float getMatrixScale(Matrix groupStackedMatrix) {
-            // Given unit vectors A = (0, 1) and B = (1, 0).
-            // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
-            // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
-            // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
-            // If  max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
-            //
-            // For non-skew case, which is most of the cases, matrix scale is computing exactly the
-            // scale on x and y axis, and take the minimal of these two.
-            // For skew case, an unit square will mapped to a parallelogram. And this function will
-            // return the minimal height of the 2 bases.
-            float[] unitVectors = new float[]{0, 1, 1, 0};
-            groupStackedMatrix.mapVectors(unitVectors);
-            float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
-            float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
-            float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
-                    unitVectors[2], unitVectors[3]);
-            float maxScale = MathUtils.max(scaleX, scaleY);
-
-            float matrixScale = 0;
-            if (maxScale > 0) {
-                matrixScale = MathUtils.abs(crossProduct) / maxScale;
-            }
-            if (DBG_VECTOR_DRAWABLE) {
-                Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
-            }
-            return matrixScale;
-        }
-
-        @Override
-        public void setName(String name) {
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we
-            // need to free it here.
-            VNativeObject nativeObject = sPathManager.getDelegate(mRootGroupPtr);
-            sPathManager.removeJavaReferenceFor(mRootGroupPtr);
-            assert nativeObject != null;
-            nativeObject.dispose();
-
-            super.finalize();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
deleted file mode 100644
index afbe97c..0000000
--- a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Delegate overriding selected methods of android.os.HandlerThread
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class HandlerThread_Delegate {
-
-    private static Map<BridgeContext, List<HandlerThread>> sThreads =
-            new HashMap<BridgeContext, List<HandlerThread>>();
-
-    public static void cleanUp(BridgeContext context) {
-        List<HandlerThread> list = sThreads.get(context);
-        if (list != null) {
-            for (HandlerThread thread : list) {
-                thread.quit();
-            }
-
-            list.clear();
-            sThreads.remove(context);
-        }
-    }
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static void run(HandlerThread theThread) {
-        // record the thread so that it can be quit() on clean up.
-        BridgeContext context = RenderAction.getCurrentContext();
-        List<HandlerThread> list = sThreads.get(context);
-        if (list == null) {
-            list = new ArrayList<HandlerThread>();
-            sThreads.put(context, list);
-        }
-
-        list.add(theThread);
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        theThread.mTid = Process.myTid();
-        Looper.prepare();
-        synchronized (theThread) {
-            theThread.mLooper = Looper.myLooper();
-            theThread.notifyAll();
-        }
-        Process.setThreadPriority(theThread.mPriority);
-        theThread.onLooperPrepared();
-        Looper.loop();
-        theThread.mTid = -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
deleted file mode 100644
index 2152c8a..0000000
--- a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate overriding selected methods of android.os.Handler
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- *
- */
-public class Handler_Delegate {
-
-    // -------- Delegate methods
-
-    @LayoutlibDelegate
-    /*package*/ static boolean sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-        // get the callback
-        IHandlerCallback callback = sCallbacks.get();
-        if (callback != null) {
-            callback.sendMessageAtTime(handler, msg, uptimeMillis);
-        }
-        return true;
-    }
-
-    // -------- Delegate implementation
-
-    public interface IHandlerCallback {
-        void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis);
-    }
-
-    private final static ThreadLocal<IHandlerCallback> sCallbacks =
-        new ThreadLocal<IHandlerCallback>();
-
-    public static void setCallback(IHandlerCallback callback) {
-        sCallbacks.set(callback);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java b/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
deleted file mode 100644
index 09f3e47..0000000
--- a/tools/layoutlib/bridge/src/android/os/Looper_Accessor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.os;
-
-import java.lang.reflect.Field;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class Looper_Accessor {
-
-    public static void cleanupThread() {
-        // clean up the looper
-        Looper.sThreadLocal.remove();
-        try {
-            Field sMainLooper = Looper.class.getDeclaredField("sMainLooper");
-            sMainLooper.setAccessible(true);
-            sMainLooper.set(null, null);
-        } catch (SecurityException e) {
-            catchReflectionException();
-        } catch (IllegalArgumentException e) {
-            catchReflectionException();
-        } catch (NoSuchFieldException e) {
-            catchReflectionException();
-        } catch (IllegalAccessException e) {
-            catchReflectionException();
-        }
-
-    }
-
-    private static void catchReflectionException() {
-        assert(false);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/ServiceManager.java b/tools/layoutlib/bridge/src/android/os/ServiceManager.java
deleted file mode 100644
index 34c7845..0000000
--- a/tools/layoutlib/bridge/src/android/os/ServiceManager.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import java.util.Map;
-
-public final class ServiceManager {
-
-    /**
-     * Returns a reference to a service with the given name.
-     *
-     * @param name the name of the service to get
-     * @return a reference to the service, or <code>null</code> if the service doesn't exist
-     */
-    public static IBinder getService(String name) {
-        return null;
-    }
-
-    /**
-     * Is not supposed to return null, but that is fine for layoutlib.
-     */
-    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
-        throw new ServiceNotFoundException(name);
-    }
-
-    /**
-     * Place a new @a service called @a name into the service
-     * manager.
-     *
-     * @param name the name of the new service
-     * @param service the service object
-     */
-    public static void addService(String name, IBinder service) {
-        // pass
-    }
-
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Non-blocking.
-     */
-    public static IBinder checkService(String name) {
-        return null;
-    }
-
-    /**
-     * Return a list of all currently running services.
-     * @return an array of all currently running services, or <code>null</code> in
-     * case of an exception
-     */
-    public static String[] listServices() {
-        // actual implementation returns null sometimes, so it's ok
-        // to return null instead of an empty list.
-        return null;
-    }
-
-    /**
-     * This is only intended to be called when the process is first being brought
-     * up and bound by the activity manager. There is only one thread in the process
-     * at that time, so no locking is done.
-     *
-     * @param cache the cache of service references
-     * @hide
-     */
-    public static void initServiceCache(Map<String, IBinder> cache) {
-        // pass
-    }
-
-    /**
-     * Exception thrown when no service published for given name. This might be
-     * thrown early during boot before certain services have published
-     * themselves.
-     *
-     * @hide
-     */
-    public static class ServiceNotFoundException extends Exception {
-        // identical to the original implementation
-        public ServiceNotFoundException(String name) {
-            super("No service published for: " + name);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
deleted file mode 100644
index 9677aaf..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-/**
- * Delegate implementing the native methods of android.os.SystemClock
- *
- * Through the layoutlib_create tool, the original native methods of SystemClock have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- *
- */
-public class SystemClock_Delegate {
-    /**
-     * Returns milliseconds since boot, not counting time spent in deep sleep.
-     * <b>Note:</b> This value may get reset occasionally (before it would
-     * otherwise wrap around).
-     *
-     * @return milliseconds of non-sleep uptime since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long uptimeMillis() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns milliseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed milliseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtime() {
-        return System_Delegate.currentTimeMillis() - System_Delegate.bootTimeMillis();
-    }
-
-    /**
-     * Returns nanoseconds since boot, including time spent in sleep.
-     *
-     * @return elapsed nanoseconds since boot.
-     */
-    @LayoutlibDelegate
-    /*package*/ static long elapsedRealtimeNanos() {
-        return System_Delegate.nanoTime() - System_Delegate.bootTime();
-    }
-
-    /**
-     * Returns milliseconds running in the current thread.
-     *
-     * @return elapsed milliseconds in the thread
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMillis() {
-        return System_Delegate.currentTimeMillis();
-    }
-
-    /**
-     * Returns microseconds running in the current thread.
-     *
-     * @return elapsed microseconds in the thread
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentThreadTimeMicro() {
-        return System_Delegate.currentTimeMillis() * 1000;
-    }
-
-    /**
-     * Returns current wall time in  microseconds.
-     *
-     * @return elapsed microseconds in wall time
-     *
-     * @hide
-     */
-    @LayoutlibDelegate
-    /*package*/ static long currentTimeMicro() {
-        return elapsedRealtime() * 1000;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
deleted file mode 100644
index d299add..0000000
--- a/tools/layoutlib/bridge/src/android/os/SystemProperties_Delegate.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.Map;
-
-/**
- * Delegate implementing the native methods of android.os.SystemProperties
- *
- * Through the layoutlib_create tool, the original native methods of SystemProperties have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class SystemProperties_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key) {
-        return native_get(key, "");
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String native_get(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return value;
-        }
-
-        return def;
-    }
-    @LayoutlibDelegate
-    /*package*/ static int native_get_int(String key, int def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Integer.decode(value);
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long native_get_long(String key, long def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-        if (value != null) {
-            return Long.decode(value);
-        }
-
-        return def;
-    }
-
-    /**
-     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
-     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean native_get_boolean(String key, boolean def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        String value = properties.get(key);
-
-        if ("n".equals(value) || "no".equals(value) || "0".equals(value) || "false".equals(value)
-                || "off".equals(value)) {
-            return false;
-        }
-        //noinspection SimplifiableIfStatement
-        if ("y".equals(value) || "yes".equals(value) || "1".equals(value) || "true".equals(value)
-                || "on".equals(value)) {
-            return true;
-        }
-
-        return def;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_set(String key, String def) {
-        Map<String, String> properties = Bridge.getPlatformProperties();
-        properties.put(key, def);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_add_change_callback() {
-        // pass.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void native_report_sysprop_change() {
-        // pass.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java b/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
deleted file mode 100644
index aa393a9..0000000
--- a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.preference;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.InflateException;
-
-public class BridgePreferenceInflater extends PreferenceInflater {
-
-    public BridgePreferenceInflater(Context context, PreferenceManager preferenceManager) {
-        super(context, preferenceManager);
-    }
-
-    @Override
-    protected Preference onCreateItem(String name, AttributeSet attrs)
-            throws ClassNotFoundException {
-        Object viewKey = null;
-        BridgeContext bc = null;
-
-        Context context = getContext();
-        if (context instanceof BridgeContext) {
-            bc = (BridgeContext) context;
-        }
-        if (attrs instanceof BridgeXmlBlockParser) {
-            viewKey = ((BridgeXmlBlockParser) attrs).getViewCookie();
-        }
-
-        Preference preference = null;
-        try {
-            preference = super.onCreateItem(name, attrs);
-        } catch (ClassNotFoundException | InflateException exception) {
-            // name is probably not a valid preference type
-            if ("SwitchPreferenceCompat".equals(name)) {
-                preference = super.onCreateItem("SwitchPreference", attrs);
-            }
-        }
-
-        if (viewKey != null && bc != null) {
-            bc.addCookie(preference, viewKey);
-        }
-        return preference;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java b/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
deleted file mode 100644
index 2e44a77..0000000
--- a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.preference;
-
-import com.android.internal.R;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-/**
- * Delegate that provides implementation for native methods in {@link Preference}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Preference have been replaced by calls to
- * methods of the same name in this delegate class.
- */
-public class Preference_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static View getView(Preference pref, View convertView, ViewGroup parent) {
-        Context context = pref.getContext();
-        BridgeContext bc = context instanceof BridgeContext ? ((BridgeContext) context) : null;
-        convertView = pref.getView_Original(convertView, parent);
-        if (bc != null) {
-            Object cookie = bc.getCookie(pref);
-            if (cookie != null) {
-                bc.addViewKey(convertView, cookie);
-            }
-        }
-        return convertView;
-    }
-
-    /**
-     * Inflates the parser and returns the ListView containing the Preferences.
-     */
-    public static View inflatePreference(Context context, XmlPullParser parser, ViewGroup root) {
-        PreferenceManager pm = new PreferenceManager(context);
-        PreferenceInflater inflater = new BridgePreferenceInflater(context, pm);
-        PreferenceScreen ps = (PreferenceScreen) inflater.inflate(parser, null, true);
-        pm.setPreferences(ps);
-        ListView preferenceView = createContainerView(context, root);
-        ps.bind(preferenceView);
-        return preferenceView;
-    }
-
-    private static ListView createContainerView(Context context, ViewGroup root) {
-        TypedArray a = context.obtainStyledAttributes(null, R.styleable.PreferenceFragment,
-                R.attr.preferenceFragmentStyle, 0);
-        int mLayoutResId = a.getResourceId(R.styleable.PreferenceFragment_layout,
-                        R.layout.preference_list_fragment);
-        a.recycle();
-
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(mLayoutResId, root, true);
-
-        return (ListView) root.findViewById(android.R.id.list);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
deleted file mode 100644
index 38171dc..0000000
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.Bidi;
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
- *
- * Through the layoutlib_create tool, the original  methods of AndroidBidi have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class AndroidBidi_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static int runBidi(int dir, char[] chars, byte[] charInfo, int count,
-            boolean haveInfo) {
-
-        switch (dir) {
-        case 0: // Layout.DIR_REQUEST_LTR
-            dir = Bidi.LTR;
-            break;
-        case 1: // Layout.DIR_REQUEST_RTL
-            dir = Bidi.RTL;
-            break;
-        case -1: // Layout.DIR_REQUEST_DEFAULT_RTL
-            dir = Bidi.LEVEL_DEFAULT_RTL;
-            break;
-        case -2: // Layout.DIR_REQUEST_DEFAULT_LTR
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-            break;
-        default:
-            // Invalid code. Log error, assume LEVEL_DEFAULT_LTR and continue.
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Invalid direction flag", null);
-            dir = Bidi.LEVEL_DEFAULT_LTR;
-        }
-        Bidi bidi = new Bidi(chars, 0, null, 0, count, dir);
-        if (charInfo != null) {
-            for (int i = 0; i < count; ++i)
-            charInfo[i] = bidi.getLevelAt(i);
-        }
-        return bidi.getParaLevel();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
deleted file mode 100644
index 50289e9..0000000
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-// Based on the native implementation of GreedyLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class GreedyLineBreaker extends LineBreaker {
-
-    public GreedyLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks lineBreaks) {
-        BreakInfo breakInfo = new BreakInfo();
-        int lineNum = 0;
-        float width = 0, printedWidth = 0;
-        boolean breakFound = false, goodBreakFound = false;
-        int breakIndex = 0, goodBreakIndex = 0;
-        float breakWidth = 0, goodBreakWidth = 0;
-        int firstTabIndex = Integer.MAX_VALUE;
-
-        float maxWidth = mLineWidth.getLineWidth(lineNum);
-
-        int numPrimitives = mPrimitives.size();
-        // greedily fit as many characters as possible on each line
-        // loop over all primitives, and choose the best break point
-        // (if possible, a break point without splitting a word)
-        // after going over the maximum length
-        for (int i = 0; i < numPrimitives; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            // update the current line width
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                width += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    printedWidth = width;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                width = mTabStops.width(width);
-                // keep track of first tab character in the region we are examining
-                // so we can determine whether or not a line contains a tab
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            // find the best break point for the characters examined so far
-            if (printedWidth > maxWidth) {
-                //noinspection StatementWithEmptyBody
-                if (breakFound || goodBreakFound) {
-                    if (goodBreakFound) {
-                        // a true line break opportunity existed in the characters examined so far,
-                        // so there is no need to split a word
-                        i = goodBreakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                        breakInfo.mWidthsList.add(goodBreakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    } else {
-                        // must split a word because there is no other option
-                        i = breakIndex; // no +1 because of i++
-                        lineNum++;
-                        maxWidth = mLineWidth.getLineWidth(lineNum);
-                        breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                        breakInfo.mWidthsList.add(breakWidth);
-                        breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-                        firstTabIndex = Integer.MAX_VALUE;
-                    }
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                } else {
-                    // no choice, keep going... must make progress by putting at least one
-                    // character on a line, even if part of that character is cut off --
-                    // there is no other option
-                }
-            }
-
-            // update possible break points
-            if (p.type == PrimitiveType.PENALTY &&
-                    p.penalty < PENALTY_INFINITY) {
-                // this does not handle penalties with width
-
-                // handle forced line break
-                if (p.penalty == -PENALTY_INFINITY) {
-                    lineNum++;
-                    maxWidth = mLineWidth.getLineWidth(lineNum);
-                    breakInfo.mBreaksList.add(p.location);
-                    breakInfo.mWidthsList.add(printedWidth);
-                    breakInfo.mFlagsList.add(firstTabIndex < i);
-                    firstTabIndex = Integer.MAX_VALUE;
-                    printedWidth = width = 0;
-                    goodBreakFound = breakFound = false;
-                    goodBreakWidth = breakWidth = 0;
-                    continue;
-                }
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-                if (i > goodBreakIndex && printedWidth <= maxWidth) {
-                    goodBreakFound = true;
-                    goodBreakIndex = i;
-                    goodBreakWidth = printedWidth;
-                }
-            } else if (p.type == PrimitiveType.WORD_BREAK) {
-                // only do this if necessary -- we don't want to break words
-                // when possible, but sometimes it is unavoidable
-                if (i > breakIndex && (printedWidth <= maxWidth || !breakFound)) {
-                    breakFound = true;
-                    breakIndex = i;
-                    breakWidth = printedWidth;
-                }
-            }
-        }
-
-        if (breakFound || goodBreakFound) {
-            // output last break if there are more characters to output
-            if (goodBreakFound) {
-                breakInfo.mBreaksList.add(mPrimitives.get(goodBreakIndex).location);
-                breakInfo.mWidthsList.add(goodBreakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < goodBreakIndex);
-            } else {
-                breakInfo.mBreaksList.add(mPrimitives.get(breakIndex).location);
-                breakInfo.mWidthsList.add(breakWidth);
-                breakInfo.mFlagsList.add(firstTabIndex < breakIndex);
-            }
-        }
-        breakInfo.copyTo(lineBreaks);
-    }
-
-    private static class BreakInfo {
-        List<Integer> mBreaksList = new ArrayList<Integer>();
-        List<Float> mWidthsList = new ArrayList<Float>();
-        List<Boolean> mFlagsList = new ArrayList<Boolean>();
-
-        public void copyTo(LineBreaks lineBreaks) {
-            if (lineBreaks.breaks.length != mBreaksList.size()) {
-                lineBreaks.breaks = new int[mBreaksList.size()];
-                lineBreaks.widths = new float[mWidthsList.size()];
-                lineBreaks.flags = new int[mFlagsList.size()];
-            }
-
-            int i = 0;
-            for (int b : mBreaksList) {
-                lineBreaks.breaks[i] = b;
-                i++;
-            }
-            i = 0;
-            for (float b : mWidthsList) {
-                lineBreaks.widths[i] = b;
-                i++;
-            }
-            i = 0;
-            for (boolean b : mFlagsList) {
-                lineBreaks.flags[i] = b ? TAB_MASK : 0;
-                i++;
-            }
-
-            mBreaksList = null;
-            mWidthsList = null;
-            mFlagsList = null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
deleted file mode 100644
index 499e58a..0000000
--- a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-
-/**
- * Delegate that overrides implementation for certain methods in {@link android.text.Hyphenator}
- * <p/>
- * Through the layoutlib_create tool, selected methods of Hyphenator have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class Hyphenator_Delegate {
-
-    private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new
-            DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class);
-
-    @LayoutlibDelegate
-    /*package*/ static File getSystemHyphenatorLocation() {
-        // FIXME
-        return null;
-    }
-
-    /*package*/ @SuppressWarnings("UnusedParameters")  // TODO implement this.
-    static long loadHyphenator(ByteBuffer buffer, int offset, int minPrefix, int minSuffix) {
-        return sDelegateManager.addNewDelegate(new Hyphenator_Delegate());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
deleted file mode 100644
index 06e9c84..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.Collections;
-import java.util.List;
-
-// Based on the native implementation of LineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public abstract class LineBreaker {
-
-    protected static final int TAB_MASK   = 0x20000000;  // keep in sync with StaticLayout
-
-    protected final @NonNull List<Primitive> mPrimitives;
-    protected final @NonNull LineWidth mLineWidth;
-    protected final @NonNull TabStops mTabStops;
-
-    public LineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        mPrimitives = Collections.unmodifiableList(primitives);
-        mLineWidth = lineWidth;
-        mTabStops = tabStops;
-    }
-
-    public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
-}
diff --git a/tools/layoutlib/bridge/src/android/text/LineWidth.java b/tools/layoutlib/bridge/src/android/text/LineWidth.java
deleted file mode 100644
index 2ea886d..0000000
--- a/tools/layoutlib/bridge/src/android/text/LineWidth.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-// Based on the native implementation of LineWidth in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class LineWidth {
-    private final float mFirstWidth;
-    private final int mFirstWidthLineCount;
-    private float mRestWidth;
-
-    public LineWidth(float firstWidth, int firstWidthLineCount, float restWidth) {
-        mFirstWidth = firstWidth;
-        mFirstWidthLineCount = firstWidthLineCount;
-        mRestWidth = restWidth;
-    }
-
-    public float getLineWidth(int line) {
-        return (line < mFirstWidthLineCount) ? mFirstWidth : mRestWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java b/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
deleted file mode 100644
index ed8e33a..0000000
--- a/tools/layoutlib/bridge/src/android/text/OptimizingLineBreaker.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ListIterator;
-
-import static android.text.Primitive.PrimitiveType.PENALTY_INFINITY;
-
-
-// Based on the native implementation of OptimizingLineBreaker in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-/**
- * A more complex version of line breaking where we try to prevent the right edge from being too
- * jagged.
- */
-public class OptimizingLineBreaker extends LineBreaker {
-
-    public OptimizingLineBreaker(@NonNull List<Primitive> primitives, @NonNull LineWidth lineWidth,
-            @NonNull TabStops tabStops) {
-        super(primitives, lineWidth, tabStops);
-    }
-
-    @Override
-    public void computeBreaks(@NonNull LineBreaks breakInfo) {
-        int numBreaks = mPrimitives.size();
-        assert numBreaks > 0;
-        if (numBreaks == 1) {
-            // This can be true only if it's an empty paragraph.
-            Primitive p = mPrimitives.get(0);
-            assert p.type == PrimitiveType.PENALTY;
-            breakInfo.breaks = new int[]{0};
-            breakInfo.widths = new float[]{p.width};
-            breakInfo.flags = new int[]{0};
-            return;
-        }
-        Node[] opt = new Node[numBreaks];
-        opt[0] = new Node(-1, 0, 0, 0, false);
-        opt[numBreaks - 1] = new Node(-1, 0, 0, 0, false);
-
-        ArrayList<Integer> active = new ArrayList<Integer>();
-        active.add(0);
-        int lastBreak = 0;
-        for (int i = 0; i < numBreaks; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.PENALTY) {
-                boolean finalBreak = (i + 1 == numBreaks);
-                Node bestBreak = null;
-
-                for (ListIterator<Integer> it = active.listIterator(); it.hasNext();
-                        /* incrementing done in loop */) {
-                    int pos = it.next();
-                    int lines = opt[pos].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    // we have to compute metrics every time --
-                    // we can't really pre-compute this stuff and just deal with breaks
-                    // because of the way tab characters work, this makes it computationally
-                    // harder, but this way, we can still optimize while treating tab characters
-                    // correctly
-                    LineMetrics lineMetrics = computeMetrics(pos, i);
-                    if (lineMetrics.mPrintedWidth <= maxWidth) {
-                        float demerits = computeDemerits(maxWidth, lineMetrics.mPrintedWidth,
-                                finalBreak, p.penalty) + opt[pos].mDemerits;
-                        if (bestBreak == null || demerits < bestBreak.mDemerits) {
-                            if (bestBreak == null) {
-                                bestBreak = new Node(pos, opt[pos].mPrevCount + 1, demerits,
-                                        lineMetrics.mPrintedWidth, lineMetrics.mHasTabs);
-                            } else {
-                                bestBreak.mPrev = pos;
-                                bestBreak.mPrevCount = opt[pos].mPrevCount + 1;
-                                bestBreak.mDemerits = demerits;
-                                bestBreak.mWidth = lineMetrics.mPrintedWidth;
-                                bestBreak.mHasTabs = lineMetrics.mHasTabs;
-                            }
-                        }
-                    } else {
-                        it.remove();
-                    }
-                }
-                if (p.penalty == -PENALTY_INFINITY) {
-                    active.clear();
-                }
-                if (bestBreak != null) {
-                    opt[i] = bestBreak;
-                    active.add(i);
-                    lastBreak = i;
-                }
-                if (active.isEmpty()) {
-                    // we can't give up!
-                    LineMetrics lineMetrics = new LineMetrics();
-                    int lines = opt[lastBreak].mPrevCount;
-                    float maxWidth = mLineWidth.getLineWidth(lines);
-                    int breakIndex = desperateBreak(lastBreak, numBreaks, maxWidth, lineMetrics);
-                    opt[breakIndex] = new Node(lastBreak, lines + 1, 0 /*doesn't matter*/,
-                            lineMetrics.mWidth, lineMetrics.mHasTabs);
-                    active.add(breakIndex);
-                    lastBreak = breakIndex;
-                    i = breakIndex; // incremented by i++
-                }
-            }
-        }
-
-        int idx = numBreaks - 1;
-        int count = opt[idx].mPrevCount;
-        resize(breakInfo, count);
-        while (opt[idx].mPrev != -1) {
-            count--;
-            assert count >=0;
-
-            breakInfo.breaks[count] = mPrimitives.get(idx).location;
-            breakInfo.widths[count] = opt[idx].mWidth;
-            breakInfo.flags [count] = opt[idx].mHasTabs ? TAB_MASK : 0;
-            idx = opt[idx].mPrev;
-        }
-    }
-
-    private static void resize(LineBreaks lineBreaks, int size) {
-        if (lineBreaks.breaks.length == size) {
-            return;
-        }
-        int[] breaks = new int[size];
-        float[] widths = new float[size];
-        int[] flags = new int[size];
-
-        int toCopy = Math.min(size, lineBreaks.breaks.length);
-        System.arraycopy(lineBreaks.breaks, 0, breaks, 0, toCopy);
-        System.arraycopy(lineBreaks.widths, 0, widths, 0, toCopy);
-        System.arraycopy(lineBreaks.flags, 0, flags, 0, toCopy);
-
-        lineBreaks.breaks = breaks;
-        lineBreaks.widths = widths;
-        lineBreaks.flags = flags;
-    }
-
-    @NonNull
-    private LineMetrics computeMetrics(int start, int end) {
-        boolean f = false;
-        float w = 0, pw = 0;
-        for (int i = start; i < end; i++) {
-            Primitive p = mPrimitives.get(i);
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                f = true;
-            }
-        }
-        return new LineMetrics(w, pw, f);
-    }
-
-    private static float computeDemerits(float maxWidth, float width, boolean finalBreak,
-            float penalty) {
-        float deviation = finalBreak ? 0 : maxWidth - width;
-        return (deviation * deviation) + penalty;
-    }
-
-    /**
-     * @return the last break position or -1 if failed.
-     */
-    @SuppressWarnings("ConstantConditions")  // method too complex to be analyzed.
-    private int desperateBreak(int start, int limit, float maxWidth,
-            @NonNull LineMetrics lineMetrics) {
-        float w = 0, pw = 0;
-        boolean breakFound = false;
-        int breakIndex = 0, firstTabIndex = Integer.MAX_VALUE;
-        for (int i = start; i < limit; i++) {
-            Primitive p = mPrimitives.get(i);
-
-            if (p.type == PrimitiveType.BOX || p.type == PrimitiveType.GLUE) {
-                w += p.width;
-                if (p.type == PrimitiveType.BOX) {
-                    pw = w;
-                }
-            } else if (p.type == PrimitiveType.VARIABLE) {
-                w = mTabStops.width(w);
-                firstTabIndex = Math.min(firstTabIndex, i);
-            }
-
-            if (pw > maxWidth && breakFound) {
-                break;
-            }
-
-            // must make progress
-            if (i > start &&
-                    (p.type == PrimitiveType.PENALTY || p.type == PrimitiveType.WORD_BREAK)) {
-                breakFound = true;
-                breakIndex = i;
-            }
-        }
-
-        if (breakFound) {
-            lineMetrics.mWidth = w;
-            lineMetrics.mPrintedWidth = pw;
-            lineMetrics.mHasTabs = (start <= firstTabIndex && firstTabIndex < breakIndex);
-            return breakIndex;
-        } else {
-            return -1;
-        }
-    }
-
-    private static class LineMetrics {
-        /** Actual width of the line. */
-        float mWidth;
-        /** Width of the line minus trailing whitespace. */
-        float mPrintedWidth;
-        boolean mHasTabs;
-
-        public LineMetrics() {
-        }
-
-        public LineMetrics(float width, float printedWidth, boolean hasTabs) {
-            mWidth = width;
-            mPrintedWidth = printedWidth;
-            mHasTabs = hasTabs;
-        }
-    }
-
-    /**
-     * A struct to store the info about a break.
-     */
-    @SuppressWarnings("SpellCheckingInspection")  // For the word struct.
-    private static class Node {
-        // -1 for the first node.
-        int mPrev;
-        // number of breaks so far.
-        int mPrevCount;
-        float mDemerits;
-        float mWidth;
-        boolean mHasTabs;
-
-        public Node(int prev, int prevCount, float demerits, float width, boolean hasTabs) {
-            mPrev = prev;
-            mPrevCount = prevCount;
-            mDemerits = demerits;
-            mWidth = width;
-            mHasTabs = hasTabs;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/Primitive.java b/tools/layoutlib/bridge/src/android/text/Primitive.java
deleted file mode 100644
index 37ed072..0000000
--- a/tools/layoutlib/bridge/src/android/text/Primitive.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.NonNull;
-
-// Based on the native implementation of Primitive in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class Primitive {
-    public final @NonNull PrimitiveType type;
-    public final int location;
-    // The following fields don't make sense for all types.
-    // Box and Glue have width only.
-    // Penalty has both width and penalty.
-    // Word_break has penalty only.
-    public final float width;
-    public final float penalty;
-
-    /**
-     * Use {@code PrimitiveType#getNewPrimitive()}
-     */
-    private Primitive(@NonNull PrimitiveType type, int location, float width, float penalty) {
-        this.type = type;
-        this.location = location;
-        this.width = width;
-        this.penalty = penalty;
-    }
-
-    public static enum PrimitiveType {
-        /**
-         * Something with a constant width that is to be typeset - like a character.
-         */
-        BOX,
-        /**
-         * Blank space with fixed width.
-         */
-        GLUE,
-        /**
-         * Aesthetic cost indicating how desirable breaking at this point will be. A penalty of
-         * {@link #PENALTY_INFINITY} means a forced non-break, whereas a penalty of negative
-         * {@code #PENALTY_INFINITY} means a forced break.
-         * <p/>
-         * Currently, it only stores penalty with values 0 or -infinity.
-         */
-        PENALTY,
-        /**
-         * For tabs - variable width space.
-         */
-        VARIABLE,
-        /**
-         * Possible breakpoints within a word. Think of this as a high cost {@link #PENALTY}.
-         */
-        WORD_BREAK;
-
-        public Primitive getNewPrimitive(int location) {
-            assert this == VARIABLE;
-            return new Primitive(this, location, 0f, 0f);
-        }
-
-        public Primitive getNewPrimitive(int location, float value) {
-            assert this == BOX || this == GLUE || this == WORD_BREAK;
-            if (this == BOX || this == GLUE) {
-                return new Primitive(this, location, value, 0f);
-            } else {
-                return new Primitive(this, location, 0f, value);
-            }
-        }
-
-        public Primitive getNewPrimitive(int location, float width, float penalty) {
-            assert this == PENALTY;
-            return new Primitive(this, location, width, penalty);
-        }
-
-        // forced non-break, negative infinity is forced break.
-        public static final float PENALTY_INFINITY = 1e7f;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
deleted file mode 100644
index cc03143..0000000
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package android.text;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.BidiRenderer;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.RectF;
-import android.icu.text.BreakIterator;
-import android.icu.util.ULocale;
-import android.text.Primitive.PrimitiveType;
-import android.text.StaticLayout.LineBreaks;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.text.Segment;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
- * <p/>
- * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class StaticLayout_Delegate {
-
-    private static final char CHAR_SPACE     = 0x20;
-    private static final char CHAR_TAB       = 0x09;
-    private static final char CHAR_NEWLINE   = 0x0A;
-    private static final char CHAR_ZWSP      = 0x200B;  // Zero width space.
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<Builder> sBuilderManager =
-        new DelegateManager<Builder>(Builder.class);
-
-    @LayoutlibDelegate
-    /*package*/ static long nNewBuilder() {
-        return sBuilderManager.addNewDelegate(new Builder());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFreeBuilder(long nativeBuilder) {
-        sBuilderManager.removeJavaReferenceFor(nativeBuilder);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinishBuilder(long nativeBuilder) {
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nLoadHyphenator(ByteBuffer buf, int offset, int minPrefix,
-            int minSuffix) {
-        return Hyphenator_Delegate.loadHyphenator(buf, offset, minPrefix, minSuffix);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            builder.mLocale = locale;
-            builder.mNativeHyphenator = nativeHyphenator;
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) {
-        // TODO.
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
-            float firstWidth, int firstWidthLineCount, float restWidth,
-            int[] variableTabStops, int defaultTabStop, int breakStrategy,
-            int hyphenationFrequency, boolean isJustified) {
-        // TODO: implement justified alignment
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-
-        builder.mText = text;
-        builder.mWidths = new float[length];
-        builder.mLineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
-        builder.mTabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
-            int start, int end, boolean isRtl) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-
-        int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
-        return builder == null ? 0 :
-                measureText(nativePaint, builder.mText, start, end - start, builder.mWidths,
-                        bidiFlags);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(widths, start, builder.mWidths, start, end - start);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return;
-        }
-        builder.mWidths[start] = width;
-        Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder != null) {
-            System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int nComputeLineBreaks(long nativeBuilder,
-            LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths,
-            int[] recycleFlags, int recycleLength) {
-
-        Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-        if (builder == null) {
-            return 0;
-        }
-
-        // compute all possible breakpoints.
-        int length = builder.mWidths.length;
-        BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
-        it.setText(new Segment(builder.mText, 0, length));
-
-        // average word length in english is 5. So, initialize the possible breaks with a guess.
-        List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
-        int loc;
-        it.first();
-        while ((loc = it.next()) != BreakIterator.DONE) {
-            breaks.add(loc);
-        }
-
-        List<Primitive> primitives =
-                computePrimitives(builder.mText, builder.mWidths, length, breaks);
-        switch (builder.mBreakStrategy) {
-            case Layout.BREAK_STRATEGY_SIMPLE:
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            case Layout.BREAK_STRATEGY_HIGH_QUALITY:
-                // TODO
-//                break;
-            case Layout.BREAK_STRATEGY_BALANCED:
-                builder.mLineBreaker = new OptimizingLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-                break;
-            default:
-                assert false : "Unknown break strategy: " + builder.mBreakStrategy;
-                builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth,
-                        builder.mTabStopCalculator);
-        }
-        builder.mLineBreaker.computeBreaks(recycle);
-        return recycle.breaks.length;
-    }
-
-    /**
-     * Compute metadata each character - things which help in deciding if it's possible to break
-     * at a point or not.
-     */
-    @NonNull
-    private static List<Primitive> computePrimitives(@NonNull char[] text, @NonNull float[] widths,
-            int length, @NonNull List<Integer> breaks) {
-        // Initialize the list with a guess of the number of primitives:
-        // 2 Primitives per non-whitespace char and approx 5 chars per word (i.e. 83% chars)
-        List<Primitive> primitives = new ArrayList<Primitive>(((int) Math.ceil(length * 1.833)));
-        int breaksSize = breaks.size();
-        int breakIndex = 0;
-        for (int i = 0; i < length; i++) {
-            char c = text[i];
-            if (c == CHAR_SPACE || c == CHAR_ZWSP) {
-                primitives.add(PrimitiveType.GLUE.getNewPrimitive(i, widths[i]));
-            } else if (c == CHAR_TAB) {
-                primitives.add(PrimitiveType.VARIABLE.getNewPrimitive(i));
-            } else if (c != CHAR_NEWLINE) {
-                while (breakIndex < breaksSize && breaks.get(breakIndex) < i) {
-                    breakIndex++;
-                }
-                Primitive p;
-                if (widths[i] != 0) {
-                    if (breakIndex < breaksSize && breaks.get(breakIndex) == i) {
-                        p = PrimitiveType.PENALTY.getNewPrimitive(i, 0, 0);
-                    } else {
-                        p = PrimitiveType.WORD_BREAK.getNewPrimitive(i, 0);
-                    }
-                    primitives.add(p);
-                }
-
-                primitives.add(PrimitiveType.BOX.getNewPrimitive(i, widths[i]));
-            }
-        }
-        // final break at end of everything
-        primitives.add(
-                PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY));
-        return primitives;
-    }
-
-    private static float measureText(long nativePaint, char []text, int index, int count,
-            float[] widths, int bidiFlags) {
-        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
-        RectF bounds = new BidiRenderer(null, paint, text)
-            .renderText(index, index + count, bidiFlags, widths, 0, false);
-        return bounds.right - bounds.left;
-    }
-
-    // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker.
-    /**
-     * Java representation of the native Builder class.
-     */
-    private static class Builder {
-        String mLocale;
-        char[] mText;
-        float[] mWidths;
-        LineBreaker mLineBreaker;
-        long mNativeHyphenator;
-        int mBreakStrategy;
-        LineWidth mLineWidth;
-        TabStops mTabStopCalculator;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/TabStops.java b/tools/layoutlib/bridge/src/android/text/TabStops.java
deleted file mode 100644
index 6c2f1e1..0000000
--- a/tools/layoutlib/bridge/src/android/text/TabStops.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text;
-
-import android.annotation.Nullable;
-
-// Based on the native implementation of TabStops in
-// frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
-public class TabStops {
-    @Nullable
-    private int[] mStops;
-    private final int mTabWidth;
-
-    public TabStops(@Nullable int[] stops, int defaultTabWidth) {
-        mTabWidth = defaultTabWidth;
-        mStops = stops;
-    }
-
-    public float width(float widthSoFar) {
-        if (mStops != null) {
-            for (int i : mStops) {
-                if (i > widthSoFar) {
-                    return i;
-                }
-            }
-        }
-        // find the next tabStop after widthSoFar.
-        return (int) ((widthSoFar + mTabWidth) / mTabWidth) * mTabWidth;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java b/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
deleted file mode 100644
index 1e4f213..0000000
--- a/tools/layoutlib/bridge/src/android/text/format/DateFormat_Delegate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.text.format;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-
-
-/**
- * Delegate used to provide new implementation for the native methods of {@link DateFormat}
- *
- * Through the layoutlib_create tool, the original  methods of DateFormat have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class DateFormat_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context) {
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean is24HourFormat(Context context, int userHandle) {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
deleted file mode 100644
index 9fd1e15..0000000
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-
-import java.util.Map;
-import java.util.function.Function;
-
-/**
- * A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
- */
-public class BridgeXmlPullAttributes extends XmlPullAttributes {
-
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-    private final Function<String, Map<String, Integer>> mFrameworkEnumValueSupplier;
-    private final Function<String, Map<String, Integer>> mProjectEnumValueSupplier;
-
-    // VisibleForTesting
-    BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile,
-            @NonNull Function<String, Map<String, Integer>> frameworkEnumValueSupplier,
-            @NonNull Function<String, Map<String, Integer>> projectEnumValueSupplier) {
-        super(parser);
-        mContext = context;
-        mPlatformFile = platformFile;
-        mFrameworkEnumValueSupplier = frameworkEnumValueSupplier;
-        mProjectEnumValueSupplier = projectEnumValueSupplier;
-    }
-
-    public BridgeXmlPullAttributes(@NonNull XmlPullParser parser, @NonNull BridgeContext context,
-            boolean platformFile) {
-        this(parser, context, platformFile, Bridge::getEnumValues, attrName -> {
-            // get the styleable matching the resolved name
-            RenderResources res = context.getRenderResources();
-            ResourceValue attr = res.getProjectResource(ResourceType.ATTR, attrName);
-            return attr instanceof AttrResourceValue ?
-                    ((AttrResourceValue) attr).getAttributeValues() : null;
-        });
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see android.util.XmlPullAttributes#getAttributeNameResource(int)
-     *
-     * This methods must return com.android.internal.R.attr.<name> matching
-     * the name of the attribute.
-     * It returns 0 if it doesn't find anything.
-     */
-    @Override
-    public int getAttributeNameResource(int index) {
-        // get the attribute name.
-        String name = getAttributeName(index);
-
-        // get the attribute namespace
-        String ns = mParser.getAttributeNamespace(index);
-
-        if (BridgeConstants.NS_RESOURCES.equals(ns)) {
-            return Bridge.getResourceId(ResourceType.ATTR, name);
-
-        }
-
-        // this is not an attribute in the android namespace, we query the customviewloader, if
-        // the namespaces match.
-        if (mContext.getLayoutlibCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getLayoutlibCallback().getResourceId(ResourceType.ATTR, name);
-            if (v != null) {
-                return v;
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToList(value, options, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value == null) {
-            return defaultValue;
-        }
-
-        ResourceValue r = getResourceValue(value);
-
-        if (r != null) {
-            value = r.getValue();
-        }
-
-        if (value.charAt(0) == '#') {
-            return ResourceHelper.getColor(value);
-        }
-
-        try {
-            return XmlUtils.convertValueToInt(value, defaultValue);
-        } catch (NumberFormatException e) {
-            // This is probably an enum
-            Map<String, Integer> enumValues = BridgeConstants.NS_RESOURCES.equals(namespace) ?
-                    mFrameworkEnumValueSupplier.apply(attribute) :
-                    mProjectEnumValueSupplier.apply(attribute);
-
-            Integer enumValue = enumValues != null ? enumValues.get(value) : null;
-            if (enumValue != null) {
-                return enumValue;
-            }
-
-            // We weren't able to find the enum int value
-            throw e;
-        }
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        String value = getAttributeValue(namespace, attribute);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        String s = getAttributeValue(namespace, attribute);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        return XmlUtils.convertValueToList(
-            getAttributeValue(index), options, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToBoolean(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-
-        return resolveResourceValue(value, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return getAttributeIntValue(mParser.getAttributeNamespace(index),
-                getAttributeName(index)
-                , defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        String value = getAttributeValue(index);
-        if (value != null) {
-            ResourceValue r = getResourceValue(value);
-
-            if (r != null) {
-                value = r.getValue();
-            }
-
-            return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
-        }
-
-        return defaultValue;
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        String s = getAttributeValue(index);
-        if (s != null) {
-            ResourceValue r = getResourceValue(s);
-
-            if (r != null) {
-                s = r.getValue();
-            }
-
-            return Float.parseFloat(s);
-        }
-
-        return defaultValue;
-    }
-
-    // -- private helper methods
-
-    /**
-     * Returns a resolved {@link ResourceValue} from a given value.
-     */
-    private ResourceValue getResourceValue(String value) {
-        // now look for this particular value
-        RenderResources resources = mContext.getRenderResources();
-        return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
-    }
-
-    /**
-     * Resolves and return a value to its associated integer.
-     */
-    private int resolveResourceValue(String value, int defaultValue) {
-        ResourceValue resource = getResourceValue(value);
-        if (resource != null) {
-            Integer id = null;
-            if (mPlatformFile || resource.isFramework()) {
-                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
-            } else {
-                id = mContext.getLayoutlibCallback().getResourceId(
-                        resource.getResourceType(), resource.getName());
-            }
-
-            if (id != null) {
-                return id;
-            }
-        }
-
-        return defaultValue;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java b/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
deleted file mode 100644
index 7f432ab..0000000
--- a/tools/layoutlib/bridge/src/android/util/Log_Delegate.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-class Log_Delegate {
-    // to replicate prefix visible when using 'adb logcat'
-    private static char priorityChar(int priority) {
-        switch (priority) {
-            case Log.VERBOSE:
-                return 'V';
-            case Log.DEBUG:
-                return 'D';
-            case Log.INFO:
-                return 'I';
-            case Log.WARN:
-                return 'W';
-            case Log.ERROR:
-                return 'E';
-            case Log.ASSERT:
-                return 'A';
-            default:
-                return '?';
-        }
-    }
-
-    @LayoutlibDelegate
-    static int println_native(int bufID, int priority, String tag, String msgs) {
-        String prefix = priorityChar(priority) + "/" + tag + ": ";
-        for (String msg: msgs.split("\n")) {
-            System.out.println(prefix + msg);
-        }
-        return 0;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/util/LruCache.java b/tools/layoutlib/bridge/src/android/util/LruCache.java
deleted file mode 100644
index 5208606..0000000
--- a/tools/layoutlib/bridge/src/android/util/LruCache.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * BEGIN LAYOUTLIB CHANGE
- * This is a custom version that doesn't use the non standard LinkedHashMap#eldest.
- * END LAYOUTLIB CHANGE
- *
- * A cache that holds strong references to a limited number of values. Each time
- * a value is accessed, it is moved to the head of a queue. When a value is
- * added to a full cache, the value at the end of that queue is evicted and may
- * become eligible for garbage collection.
- *
- * <p>If your cached values hold resources that need to be explicitly released,
- * override {@link #entryRemoved}.
- *
- * <p>If a cache miss should be computed on demand for the corresponding keys,
- * override {@link #create}. This simplifies the calling code, allowing it to
- * assume a value will always be returned, even when there's a cache miss.
- *
- * <p>By default, the cache size is measured in the number of entries. Override
- * {@link #sizeOf} to size the cache in different units. For example, this cache
- * is limited to 4MiB of bitmaps:
- * <pre>   {@code
- *   int cacheSize = 4 * 1024 * 1024; // 4MiB
- *   LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
- *       protected int sizeOf(String key, Bitmap value) {
- *           return value.getByteCount();
- *       }
- *   }}</pre>
- *
- * <p>This class is thread-safe. Perform multiple cache operations atomically by
- * synchronizing on the cache: <pre>   {@code
- *   synchronized (cache) {
- *     if (cache.get(key) == null) {
- *         cache.put(key, value);
- *     }
- *   }}</pre>
- *
- * <p>This class does not allow null to be used as a key or value. A return
- * value of null from {@link #get}, {@link #put} or {@link #remove} is
- * unambiguous: the key was not in the cache.
- *
- * <p>This class appeared in Android 3.1 (Honeycomb MR1); it's available as part
- * of <a href="http://developer.android.com/sdk/compatibility-library.html">Android's
- * Support Package</a> for earlier releases.
- */
-public class LruCache<K, V> {
-    private final LinkedHashMap<K, V> map;
-
-    /** Size of this cache in units. Not necessarily the number of elements. */
-    private int size;
-    private int maxSize;
-
-    private int putCount;
-    private int createCount;
-    private int evictionCount;
-    private int hitCount;
-    private int missCount;
-
-    /**
-     * @param maxSize for caches that do not override {@link #sizeOf}, this is
-     *     the maximum number of entries in the cache. For all other caches,
-     *     this is the maximum sum of the sizes of the entries in this cache.
-     */
-    public LruCache(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-        this.maxSize = maxSize;
-        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
-    }
-
-    /**
-     * Sets the size of the cache.
-     * @param maxSize The new maximum size.
-     *
-     * @hide
-     */
-    public void resize(int maxSize) {
-        if (maxSize <= 0) {
-            throw new IllegalArgumentException("maxSize <= 0");
-        }
-
-        synchronized (this) {
-            this.maxSize = maxSize;
-        }
-        trimToSize(maxSize);
-    }
-
-    /**
-     * Returns the value for {@code key} if it exists in the cache or can be
-     * created by {@code #create}. If a value was returned, it is moved to the
-     * head of the queue. This returns null if a value is not cached and cannot
-     * be created.
-     */
-    public final V get(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V mapValue;
-        synchronized (this) {
-            mapValue = map.get(key);
-            if (mapValue != null) {
-                hitCount++;
-                return mapValue;
-            }
-            missCount++;
-        }
-
-        /*
-         * Attempt to create a value. This may take a long time, and the map
-         * may be different when create() returns. If a conflicting value was
-         * added to the map while create() was working, we leave that value in
-         * the map and release the created value.
-         */
-
-        V createdValue = create(key);
-        if (createdValue == null) {
-            return null;
-        }
-
-        synchronized (this) {
-            createCount++;
-            mapValue = map.put(key, createdValue);
-
-            if (mapValue != null) {
-                // There was a conflict so undo that last put
-                map.put(key, mapValue);
-            } else {
-                size += safeSizeOf(key, createdValue);
-            }
-        }
-
-        if (mapValue != null) {
-            entryRemoved(false, key, createdValue, mapValue);
-            return mapValue;
-        } else {
-            trimToSize(maxSize);
-            return createdValue;
-        }
-    }
-
-    /**
-     * Caches {@code value} for {@code key}. The value is moved to the head of
-     * the queue.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V put(K key, V value) {
-        if (key == null || value == null) {
-            throw new NullPointerException("key == null || value == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            putCount++;
-            size += safeSizeOf(key, value);
-            previous = map.put(key, value);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, value);
-        }
-
-        trimToSize(maxSize);
-        return previous;
-    }
-
-    /**
-     * @param maxSize the maximum size of the cache before returning. May be -1
-     *     to evict even 0-sized elements.
-     */
-    private void trimToSize(int maxSize) {
-        while (true) {
-            K key;
-            V value;
-            synchronized (this) {
-                if (size < 0 || (map.isEmpty() && size != 0)) {
-                    throw new IllegalStateException(getClass().getName()
-                            + ".sizeOf() is reporting inconsistent results!");
-                }
-
-                if (size <= maxSize) {
-                    break;
-                }
-
-                // BEGIN LAYOUTLIB CHANGE
-                // get the last item in the linked list.
-                // This is not efficient, the goal here is to minimize the changes
-                // compared to the platform version.
-                Map.Entry<K, V> toEvict = null;
-                for (Map.Entry<K, V> entry : map.entrySet()) {
-                    toEvict = entry;
-                }
-                // END LAYOUTLIB CHANGE
-
-                if (toEvict == null) {
-                    break;
-                }
-
-                key = toEvict.getKey();
-                value = toEvict.getValue();
-                map.remove(key);
-                size -= safeSizeOf(key, value);
-                evictionCount++;
-            }
-
-            entryRemoved(true, key, value, null);
-        }
-    }
-
-    /**
-     * Removes the entry for {@code key} if it exists.
-     *
-     * @return the previous value mapped by {@code key}.
-     */
-    public final V remove(K key) {
-        if (key == null) {
-            throw new NullPointerException("key == null");
-        }
-
-        V previous;
-        synchronized (this) {
-            previous = map.remove(key);
-            if (previous != null) {
-                size -= safeSizeOf(key, previous);
-            }
-        }
-
-        if (previous != null) {
-            entryRemoved(false, key, previous, null);
-        }
-
-        return previous;
-    }
-
-    /**
-     * Called for entries that have been evicted or removed. This method is
-     * invoked when a value is evicted to make space, removed by a call to
-     * {@link #remove}, or replaced by a call to {@link #put}. The default
-     * implementation does nothing.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * @param evicted true if the entry is being removed to make space, false
-     *     if the removal was caused by a {@link #put} or {@link #remove}.
-     * @param newValue the new value for {@code key}, if it exists. If non-null,
-     *     this removal was caused by a {@link #put}. Otherwise it was caused by
-     *     an eviction or a {@link #remove}.
-     */
-    protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}
-
-    /**
-     * Called after a cache miss to compute a value for the corresponding key.
-     * Returns the computed value or null if no value can be computed. The
-     * default implementation returns null.
-     *
-     * <p>The method is called without synchronization: other threads may
-     * access the cache while this method is executing.
-     *
-     * <p>If a value for {@code key} exists in the cache when this method
-     * returns, the created value will be released with {@link #entryRemoved}
-     * and discarded. This can occur when multiple threads request the same key
-     * at the same time (causing multiple values to be created), or when one
-     * thread calls {@link #put} while another is creating a value for the same
-     * key.
-     */
-    protected V create(K key) {
-        return null;
-    }
-
-    private int safeSizeOf(K key, V value) {
-        int result = sizeOf(key, value);
-        if (result < 0) {
-            throw new IllegalStateException("Negative size: " + key + "=" + value);
-        }
-        return result;
-    }
-
-    /**
-     * Returns the size of the entry for {@code key} and {@code value} in
-     * user-defined units.  The default implementation returns 1 so that size
-     * is the number of entries and max size is the maximum number of entries.
-     *
-     * <p>An entry's size must not change while it is in the cache.
-     */
-    protected int sizeOf(K key, V value) {
-        return 1;
-    }
-
-    /**
-     * Clear the cache, calling {@link #entryRemoved} on each removed entry.
-     */
-    public final void evictAll() {
-        trimToSize(-1); // -1 will evict 0-sized elements
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the number
-     * of entries in the cache. For all other caches, this returns the sum of
-     * the sizes of the entries in this cache.
-     */
-    public synchronized final int size() {
-        return size;
-    }
-
-    /**
-     * For caches that do not override {@link #sizeOf}, this returns the maximum
-     * number of entries in the cache. For all other caches, this returns the
-     * maximum sum of the sizes of the entries in this cache.
-     */
-    public synchronized final int maxSize() {
-        return maxSize;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned a value that was
-     * already present in the cache.
-     */
-    public synchronized final int hitCount() {
-        return hitCount;
-    }
-
-    /**
-     * Returns the number of times {@link #get} returned null or required a new
-     * value to be created.
-     */
-    public synchronized final int missCount() {
-        return missCount;
-    }
-
-    /**
-     * Returns the number of times {@link #create(Object)} returned a value.
-     */
-    public synchronized final int createCount() {
-        return createCount;
-    }
-
-    /**
-     * Returns the number of times {@link #put} was called.
-     */
-    public synchronized final int putCount() {
-        return putCount;
-    }
-
-    /**
-     * Returns the number of values that have been evicted.
-     */
-    public synchronized final int evictionCount() {
-        return evictionCount;
-    }
-
-    /**
-     * Returns a copy of the current contents of the cache, ordered from least
-     * recently accessed to most recently accessed.
-     */
-    public synchronized final Map<K, V> snapshot() {
-        return new LinkedHashMap<K, V>(map);
-    }
-
-    @Override public synchronized final String toString() {
-        int accesses = hitCount + missCount;
-        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;
-        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
-                maxSize, hitCount, missCount, hitPercent);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java b/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
deleted file mode 100644
index 7b69388..0000000
--- a/tools/layoutlib/bridge/src/android/util/PathParser_Delegate.java
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.NonNull;
-import android.graphics.Path_Delegate;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Delegate that provides implementation for native methods in {@link android.util.PathParser}
- * <p/>
- * Through the layoutlib_create tool, selected methods of PathParser have been replaced by calls to
- * methods of the same name in this delegate class.
- *
- * Most of the code has been taken from the implementation in
- * {@code tools/base/sdk-common/src/main/java/com/android/ide/common/vectordrawable/PathParser.java}
- * revision be6fe89a3b686db5a75e7e692a148699973957f3
- */
-public class PathParser_Delegate {
-
-    private static final Logger LOGGER = Logger.getLogger("PathParser");
-
-    // ---- Builder delegate manager ----
-    private static final DelegateManager<PathParser_Delegate> sManager =
-            new DelegateManager<PathParser_Delegate>(PathParser_Delegate.class);
-
-    // ---- delegate data ----
-    @NonNull
-    private PathDataNode[] mPathDataNodes;
-
-    public static PathParser_Delegate getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    private PathParser_Delegate(@NonNull PathDataNode[] nodes) {
-        mPathDataNodes = nodes;
-    }
-
-    public PathDataNode[] getPathDataNodes() {
-        return mPathDataNodes;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nParseStringForPath(long pathPtr, @NonNull String pathString, int
-            stringLength) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(pathPtr);
-        if (path_delegate == null) {
-            return;
-        }
-        assert pathString.length() == stringLength;
-        PathDataNode.nodesToPath(createNodesFromPathData(pathString), path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nCreatePathFromPathData(long outPathPtr, long pathData) {
-        Path_Delegate path_delegate = Path_Delegate.getDelegate(outPathPtr);
-        PathParser_Delegate source = sManager.getDelegate(outPathPtr);
-        if (source == null || path_delegate == null) {
-            return;
-        }
-        PathDataNode.nodesToPath(source.mPathDataNodes, path_delegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreateEmptyPathData() {
-        PathParser_Delegate newDelegate = new PathParser_Delegate(new PathDataNode[0]);
-        return sManager.addNewDelegate(newDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathData(long nativePtr) {
-        PathParser_Delegate source = sManager.getDelegate(nativePtr);
-        if (source == null) {
-            return 0;
-        }
-        PathParser_Delegate dest = new PathParser_Delegate(deepCopyNodes(source.mPathDataNodes));
-        return sManager.addNewDelegate(dest);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePathDataFromString(@NonNull String pathString,
-            int stringLength) {
-        assert pathString.length() == stringLength : "Inconsistent path string length.";
-        PathDataNode[] nodes = createNodesFromPathData(pathString);
-        PathParser_Delegate delegate = new PathParser_Delegate(nodes);
-        return sManager.addNewDelegate(delegate);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
-            long toDataPtr, float fraction) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        PathParser_Delegate to = sManager.getDelegate(toDataPtr);
-        if (out == null || from == null || to == null) {
-            return false;
-        }
-        int length = from.mPathDataNodes.length;
-        if (length != to.mPathDataNodes.length) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Cannot interpolate path data with different lengths (from " + length + " to " +
-                            to.mPathDataNodes.length + ").", null);
-            return false;
-        }
-        if (out.mPathDataNodes.length != length) {
-            out.mPathDataNodes = new PathDataNode[length];
-        }
-        for (int i = 0; i < length; i++) {
-            if (out.mPathDataNodes[i] == null) {
-                out.mPathDataNodes[i] = new PathDataNode(from.mPathDataNodes[i]);
-            }
-            out.mPathDataNodes[i].interpolatePathDataNode(from.mPathDataNodes[i],
-                        to.mPathDataNodes[i], fraction);
-        }
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nFinalize(long nativePtr) {
-        sManager.removeJavaReferenceFor(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nCanMorph(long fromDataPtr, long toDataPtr) {
-        PathParser_Delegate fromPath = PathParser_Delegate.getDelegate(fromDataPtr);
-        PathParser_Delegate toPath = PathParser_Delegate.getDelegate(toDataPtr);
-        if (fromPath == null || toPath == null || fromPath.getPathDataNodes() == null || toPath
-                .getPathDataNodes() == null) {
-            return true;
-        }
-        return PathParser_Delegate.canMorph(fromPath.getPathDataNodes(), toPath.getPathDataNodes());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void nSetPathData(long outDataPtr, long fromDataPtr) {
-        PathParser_Delegate out = sManager.getDelegate(outDataPtr);
-        PathParser_Delegate from = sManager.getDelegate(fromDataPtr);
-        if (from == null || out == null) {
-            return;
-        }
-        out.mPathDataNodes = deepCopyNodes(from.mPathDataNodes);
-    }
-
-    /**
-     * @param pathData The string representing a path, the same as "d" string in svg file.
-     *
-     * @return an array of the PathDataNode.
-     */
-    @NonNull
-    public static PathDataNode[] createNodesFromPathData(@NonNull String pathData) {
-        int start = 0;
-        int end = 1;
-
-        ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
-        while (end < pathData.length()) {
-            end = nextStart(pathData, end);
-            String s = pathData.substring(start, end).trim();
-            if (s.length() > 0) {
-                float[] val = getFloats(s);
-                addNode(list, s.charAt(0), val);
-            }
-
-            start = end;
-            end++;
-        }
-        if ((end - start) == 1 && start < pathData.length()) {
-            addNode(list, pathData.charAt(start), new float[0]);
-        }
-        return list.toArray(new PathDataNode[list.size()]);
-    }
-
-    /**
-     * @param source The array of PathDataNode to be duplicated.
-     *
-     * @return a deep copy of the <code>source</code>.
-     */
-    @NonNull
-    public static PathDataNode[] deepCopyNodes(@NonNull PathDataNode[] source) {
-        PathDataNode[] copy = new PathDataNode[source.length];
-        for (int i = 0; i < source.length; i++) {
-            copy[i] = new PathDataNode(source[i]);
-        }
-        return copy;
-    }
-
-    /**
-     * @param nodesFrom The source path represented in an array of PathDataNode
-     * @param nodesTo The target path represented in an array of PathDataNode
-     * @return whether the <code>nodesFrom</code> can morph into <code>nodesTo</code>
-     */
-    public static boolean canMorph(PathDataNode[] nodesFrom, PathDataNode[] nodesTo) {
-        if (nodesFrom == null || nodesTo == null) {
-            return false;
-        }
-
-        if (nodesFrom.length != nodesTo.length) {
-            return false;
-        }
-
-        for (int i = 0; i < nodesFrom.length; i ++) {
-            if (nodesFrom[i].mType != nodesTo[i].mType
-                    || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Update the target's data to match the source.
-     * Before calling this, make sure canMorph(target, source) is true.
-     *
-     * @param target The target path represented in an array of PathDataNode
-     * @param source The source path represented in an array of PathDataNode
-     */
-    public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
-        for (int i = 0; i < source.length; i ++) {
-            target[i].mType = source[i].mType;
-            for (int j = 0; j < source[i].mParams.length; j ++) {
-                target[i].mParams[j] = source[i].mParams[j];
-            }
-        }
-    }
-
-    private static int nextStart(@NonNull String s, int end) {
-        char c;
-
-        while (end < s.length()) {
-            c = s.charAt(end);
-            // Note that 'e' or 'E' are not valid path commands, but could be
-            // used for floating point numbers' scientific notation.
-            // Therefore, when searching for next command, we should ignore 'e'
-            // and 'E'.
-            if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
-                    && c != 'e' && c != 'E') {
-                return end;
-            }
-            end++;
-        }
-        return end;
-    }
-
-    /**
-     * Calculate the position of the next comma or space or negative sign
-     *
-     * @param s the string to search
-     * @param start the position to start searching
-     * @param result the result of the extraction, including the position of the the starting
-     * position of next number, whether it is ending with a '-'.
-     */
-    private static void extract(@NonNull String s, int start, @NonNull ExtractFloatResult result) {
-        // Now looking for ' ', ',', '.' or '-' from the start.
-        int currentIndex = start;
-        boolean foundSeparator = false;
-        result.mEndWithNegOrDot = false;
-        boolean secondDot = false;
-        boolean isExponential = false;
-        for (; currentIndex < s.length(); currentIndex++) {
-            boolean isPrevExponential = isExponential;
-            isExponential = false;
-            char currentChar = s.charAt(currentIndex);
-            switch (currentChar) {
-                case ' ':
-                case ',':
-                    foundSeparator = true;
-                    break;
-                case '-':
-                    // The negative sign following a 'e' or 'E' is not a separator.
-                    if (currentIndex != start && !isPrevExponential) {
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case '.':
-                    if (!secondDot) {
-                        secondDot = true;
-                    } else {
-                        // This is the second dot, and it is considered as a separator.
-                        foundSeparator = true;
-                        result.mEndWithNegOrDot = true;
-                    }
-                    break;
-                case 'e':
-                case 'E':
-                    isExponential = true;
-                    break;
-            }
-            if (foundSeparator) {
-                break;
-            }
-        }
-        // When there is nothing found, then we put the end position to the end
-        // of the string.
-        result.mEndPosition = currentIndex;
-    }
-
-    /**
-     * Parse the floats in the string. This is an optimized version of
-     * parseFloat(s.split(",|\\s"));
-     *
-     * @param s the string containing a command and list of floats
-     *
-     * @return array of floats
-     */
-    @NonNull
-    private static float[] getFloats(@NonNull String s) {
-        if (s.charAt(0) == 'z' || s.charAt(0) == 'Z') {
-            return new float[0];
-        }
-        try {
-            float[] results = new float[s.length()];
-            int count = 0;
-            int startPosition = 1;
-            int endPosition;
-
-            ExtractFloatResult result = new ExtractFloatResult();
-            int totalLength = s.length();
-
-            // The startPosition should always be the first character of the
-            // current number, and endPosition is the character after the current
-            // number.
-            while (startPosition < totalLength) {
-                extract(s, startPosition, result);
-                endPosition = result.mEndPosition;
-
-                if (startPosition < endPosition) {
-                    results[count++] = Float.parseFloat(
-                            s.substring(startPosition, endPosition));
-                }
-
-                if (result.mEndWithNegOrDot) {
-                    // Keep the '-' or '.' sign with next number.
-                    startPosition = endPosition;
-                } else {
-                    startPosition = endPosition + 1;
-                }
-            }
-            return Arrays.copyOf(results, count);
-        } catch (NumberFormatException e) {
-            assert false : "error in parsing \"" + s + "\"" + e;
-            return new float[0];
-        }
-    }
-
-
-    private static void addNode(@NonNull ArrayList<PathDataNode> list, char cmd,
-            @NonNull float[] val) {
-        list.add(new PathDataNode(cmd, val));
-    }
-
-    private static class ExtractFloatResult {
-        // We need to return the position of the next separator and whether the
-        // next float starts with a '-' or a '.'.
-        private int mEndPosition;
-        private boolean mEndWithNegOrDot;
-    }
-
-    /**
-     * Each PathDataNode represents one command in the "d" attribute of the svg file. An array of
-     * PathDataNode can represent the whole "d" attribute.
-     */
-    public static class PathDataNode {
-        private char mType;
-        @NonNull
-        private float[] mParams;
-
-        private PathDataNode(char type, @NonNull float[] params) {
-            mType = type;
-            mParams = params;
-        }
-
-        public char getType() {
-            return mType;
-        }
-
-        @NonNull
-        public float[] getParams() {
-            return mParams;
-        }
-
-        private PathDataNode(@NonNull PathDataNode n) {
-            mType = n.mType;
-            mParams = Arrays.copyOf(n.mParams, n.mParams.length);
-        }
-
-        /**
-         * Convert an array of PathDataNode to Path. Reset the passed path as needed before
-         * calling this method.
-         *
-         * @param node The source array of PathDataNode.
-         * @param path The target Path object.
-         */
-        public static void nodesToPath(@NonNull PathDataNode[] node, @NonNull Path_Delegate path) {
-            float[] current = new float[6];
-            char previousCommand = 'm';
-            //noinspection ForLoopReplaceableByForEach
-            for (int i = 0; i < node.length; i++) {
-                addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
-                previousCommand = node[i].mType;
-            }
-        }
-
-        /**
-         * The current PathDataNode will be interpolated between the <code>nodeFrom</code> and
-         * <code>nodeTo</code> according to the <code>fraction</code>.
-         *
-         * @param nodeFrom The start value as a PathDataNode.
-         * @param nodeTo The end value as a PathDataNode
-         * @param fraction The fraction to interpolate.
-         */
-        private void interpolatePathDataNode(@NonNull PathDataNode nodeFrom,
-                @NonNull PathDataNode nodeTo, float fraction) {
-            for (int i = 0; i < nodeFrom.mParams.length; i++) {
-                mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
-                        + nodeTo.mParams[i] * fraction;
-            }
-        }
-
-        @SuppressWarnings("PointlessArithmeticExpression")
-        private static void addCommand(@NonNull Path_Delegate path, float[] current,
-                char previousCmd, char cmd, @NonNull float[] val) {
-
-            int incr = 2;
-            float currentX = current[0];
-            float currentY = current[1];
-            float ctrlPointX = current[2];
-            float ctrlPointY = current[3];
-            float currentSegmentStartX = current[4];
-            float currentSegmentStartY = current[5];
-            float reflectiveCtrlPointX;
-            float reflectiveCtrlPointY;
-
-            switch (cmd) {
-                case 'z':
-                case 'Z':
-                    path.close();
-                    // Path is closed here, but we need to move the pen to the
-                    // closed position. So we cache the segment's starting position,
-                    // and restore it here.
-                    currentX = currentSegmentStartX;
-                    currentY = currentSegmentStartY;
-                    ctrlPointX = currentSegmentStartX;
-                    ctrlPointY = currentSegmentStartY;
-                    path.moveTo(currentX, currentY);
-                    break;
-                case 'm':
-                case 'M':
-                case 'l':
-                case 'L':
-                case 't':
-                case 'T':
-                    incr = 2;
-                    break;
-                case 'h':
-                case 'H':
-                case 'v':
-                case 'V':
-                    incr = 1;
-                    break;
-                case 'c':
-                case 'C':
-                    incr = 6;
-                    break;
-                case 's':
-                case 'S':
-                case 'q':
-                case 'Q':
-                    incr = 4;
-                    break;
-                case 'a':
-                case 'A':
-                    incr = 7;
-                    break;
-            }
-
-            for (int k = 0; k < val.length; k += incr) {
-                switch (cmd) {
-                    case 'm': // moveto - Start a new sub-path (relative)
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.rLineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.rMoveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'M': // moveto - Start a new sub-path
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-
-                        if (k > 0) {
-                            // According to the spec, if a moveto is followed by multiple
-                            // pairs of coordinates, the subsequent pairs are treated as
-                            // implicit lineto commands.
-                            path.lineTo(val[k + 0], val[k + 1]);
-                        } else {
-                            path.moveTo(val[k + 0], val[k + 1]);
-                            currentSegmentStartX = currentX;
-                            currentSegmentStartY = currentY;
-                        }
-                        break;
-                    case 'l': // lineto - Draw a line from the current point (relative)
-                        path.rLineTo(val[k + 0], val[k + 1]);
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'L': // lineto - Draw a line from the current point
-                        path.lineTo(val[k + 0], val[k + 1]);
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'h': // horizontal lineto - Draws a horizontal line (relative)
-                        path.rLineTo(val[k + 0], 0);
-                        currentX += val[k + 0];
-                        break;
-                    case 'H': // horizontal lineto - Draws a horizontal line
-                        path.lineTo(val[k + 0], currentY);
-                        currentX = val[k + 0];
-                        break;
-                    case 'v': // vertical lineto - Draws a vertical line from the current point (r)
-                        path.rLineTo(0, val[k + 0]);
-                        currentY += val[k + 0];
-                        break;
-                    case 'V': // vertical lineto - Draws a vertical line from the current point
-                        path.lineTo(currentX, val[k + 0]);
-                        currentY = val[k + 0];
-                        break;
-                    case 'c': // curveto - Draws a cubic Bézier curve (relative)
-                        path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-
-                        ctrlPointX = currentX + val[k + 2];
-                        ctrlPointY = currentY + val[k + 3];
-                        currentX += val[k + 4];
-                        currentY += val[k + 5];
-
-                        break;
-                    case 'C': // curveto - Draws a cubic Bézier curve
-                        path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3],
-                                val[k + 4], val[k + 5]);
-                        currentX = val[k + 4];
-                        currentY = val[k + 5];
-                        ctrlPointX = val[k + 2];
-                        ctrlPointY = val[k + 3];
-                        break;
-                    case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rCubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1],
-                                val[k + 2], val[k + 3]);
-
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'c' || previousCmd == 's'
-                                || previousCmd == 'C' || previousCmd == 'S') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.cubicTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 'q': // Draws a quadratic Bézier (relative)
-                        path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = currentX + val[k + 0];
-                        ctrlPointY = currentY + val[k + 1];
-                        currentX += val[k + 2];
-                        currentY += val[k + 3];
-                        break;
-                    case 'Q': // Draws a quadratic Bézier
-                        path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
-                        ctrlPointX = val[k + 0];
-                        ctrlPointY = val[k + 1];
-                        currentX = val[k + 2];
-                        currentY = val[k + 3];
-                        break;
-                    case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
-                        reflectiveCtrlPointX = 0;
-                        reflectiveCtrlPointY = 0;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = currentX - ctrlPointX;
-                            reflectiveCtrlPointY = currentY - ctrlPointY;
-                        }
-                        path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = currentX + reflectiveCtrlPointX;
-                        ctrlPointY = currentY + reflectiveCtrlPointY;
-                        currentX += val[k + 0];
-                        currentY += val[k + 1];
-                        break;
-                    case 'T': // Draws a quadratic Bézier curve (reflective control point)
-                        reflectiveCtrlPointX = currentX;
-                        reflectiveCtrlPointY = currentY;
-                        if (previousCmd == 'q' || previousCmd == 't'
-                                || previousCmd == 'Q' || previousCmd == 'T') {
-                            reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
-                            reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
-                        }
-                        path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY,
-                                val[k + 0], val[k + 1]);
-                        ctrlPointX = reflectiveCtrlPointX;
-                        ctrlPointY = reflectiveCtrlPointY;
-                        currentX = val[k + 0];
-                        currentY = val[k + 1];
-                        break;
-                    case 'a': // Draws an elliptical arc
-                        // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5] + currentX,
-                                val[k + 6] + currentY,
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX += val[k + 5];
-                        currentY += val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                    case 'A': // Draws an elliptical arc
-                        drawArc(path,
-                                currentX,
-                                currentY,
-                                val[k + 5],
-                                val[k + 6],
-                                val[k + 0],
-                                val[k + 1],
-                                val[k + 2],
-                                val[k + 3] != 0,
-                                val[k + 4] != 0);
-                        currentX = val[k + 5];
-                        currentY = val[k + 6];
-                        ctrlPointX = currentX;
-                        ctrlPointY = currentY;
-                        break;
-                }
-                previousCmd = cmd;
-            }
-            current[0] = currentX;
-            current[1] = currentY;
-            current[2] = ctrlPointX;
-            current[3] = ctrlPointY;
-            current[4] = currentSegmentStartX;
-            current[5] = currentSegmentStartY;
-        }
-
-        private static void drawArc(@NonNull Path_Delegate p, float x0, float y0, float x1,
-                float y1, float a, float b, float theta, boolean isMoreThanHalf,
-                boolean isPositiveArc) {
-
-            LOGGER.log(Level.FINE, "(" + x0 + "," + y0 + ")-(" + x1 + "," + y1
-                    + ") {" + a + " " + b + "}");
-        /* Convert rotation angle from degrees to radians */
-            double thetaD = theta * Math.PI / 180.0f;
-        /* Pre-compute rotation matrix entries */
-            double cosTheta = Math.cos(thetaD);
-            double sinTheta = Math.sin(thetaD);
-        /* Transform (x0, y0) and (x1, y1) into unit space */
-        /* using (inverse) rotation, followed by (inverse) scale */
-            double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
-            double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
-            double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
-            double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
-            LOGGER.log(Level.FINE, "unit space (" + x0p + "," + y0p + ")-(" + x1p
-                    + "," + y1p + ")");
-        /* Compute differences and averages */
-            double dx = x0p - x1p;
-            double dy = y0p - y1p;
-            double xm = (x0p + x1p) / 2;
-            double ym = (y0p + y1p) / 2;
-        /* Solve for intersecting unit circles */
-            double dsq = dx * dx + dy * dy;
-            if (dsq == 0.0) {
-                LOGGER.log(Level.FINE, " Points are coincident");
-                return; /* Points are coincident */
-            }
-            double disc = 1.0 / dsq - 1.0 / 4.0;
-            if (disc < 0.0) {
-                LOGGER.log(Level.FINE, "Points are too far apart " + dsq);
-                float adjust = (float) (Math.sqrt(dsq) / 1.99999);
-                drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta,
-                        isMoreThanHalf, isPositiveArc);
-                return; /* Points are too far apart */
-            }
-            double s = Math.sqrt(disc);
-            double sdx = s * dx;
-            double sdy = s * dy;
-            double cx;
-            double cy;
-            if (isMoreThanHalf == isPositiveArc) {
-                cx = xm - sdy;
-                cy = ym + sdx;
-            } else {
-                cx = xm + sdy;
-                cy = ym - sdx;
-            }
-
-            double eta0 = Math.atan2((y0p - cy), (x0p - cx));
-            LOGGER.log(Level.FINE, "eta0 = Math.atan2( " + (y0p - cy) + " , "
-                    + (x0p - cx) + ") = " + Math.toDegrees(eta0));
-
-            double eta1 = Math.atan2((y1p - cy), (x1p - cx));
-            LOGGER.log(Level.FINE, "eta1 = Math.atan2( " + (y1p - cy) + " , "
-                    + (x1p - cx) + ") = " + Math.toDegrees(eta1));
-            double sweep = (eta1 - eta0);
-            if (isPositiveArc != (sweep >= 0)) {
-                if (sweep > 0) {
-                    sweep -= 2 * Math.PI;
-                } else {
-                    sweep += 2 * Math.PI;
-                }
-            }
-
-            cx *= a;
-            cy *= b;
-            double tcx = cx;
-            cx = cx * cosTheta - cy * sinTheta;
-            cy = tcx * sinTheta + cy * cosTheta;
-            LOGGER.log(
-                    Level.FINE,
-                    "cx, cy, a, b, x0, y0, thetaD, eta0, sweep = " + cx + " , "
-                            + cy + " , " + a + " , " + b + " , " + x0 + " , " + y0
-                            + " , " + Math.toDegrees(thetaD) + " , "
-                            + Math.toDegrees(eta0) + " , " + Math.toDegrees(sweep));
-
-            arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
-        }
-
-        /**
-         * Converts an arc to cubic Bezier segments and records them in p.
-         *
-         * @param p The target for the cubic Bezier segments
-         * @param cx The x coordinate center of the ellipse
-         * @param cy The y coordinate center of the ellipse
-         * @param a The radius of the ellipse in the horizontal direction
-         * @param b The radius of the ellipse in the vertical direction
-         * @param e1x E(eta1) x coordinate of the starting point of the arc
-         * @param e1y E(eta2) y coordinate of the starting point of the arc
-         * @param theta The angle that the ellipse bounding rectangle makes with the horizontal
-         * plane
-         * @param start The start angle of the arc on the ellipse
-         * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
-         */
-        private static void arcToBezier(@NonNull Path_Delegate p, double cx, double cy, double a,
-                double b, double e1x, double e1y, double theta, double start,
-                double sweep) {
-            // Taken from equations at:
-            // http://spaceroots.org/documents/ellipse/node8.html
-            // and http://www.spaceroots.org/documents/ellipse/node22.html
-            // Maximum of 45 degrees per cubic Bezier segment
-            int numSegments = (int) Math.ceil(Math.abs(sweep * 4 / Math.PI));
-
-
-            double eta1 = start;
-            double cosTheta = Math.cos(theta);
-            double sinTheta = Math.sin(theta);
-            double cosEta1 = Math.cos(eta1);
-            double sinEta1 = Math.sin(eta1);
-            double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
-            double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
-
-            double anglePerSegment = sweep / numSegments;
-            for (int i = 0; i < numSegments; i++) {
-                double eta2 = eta1 + anglePerSegment;
-                double sinEta2 = Math.sin(eta2);
-                double cosEta2 = Math.cos(eta2);
-                double e2x = cx + (a * cosTheta * cosEta2)
-                        - (b * sinTheta * sinEta2);
-                double e2y = cy + (a * sinTheta * cosEta2)
-                        + (b * cosTheta * sinEta2);
-                double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
-                double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
-                double tanDiff2 = Math.tan((eta2 - eta1) / 2);
-                double alpha = Math.sin(eta2 - eta1)
-                        * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
-                double q1x = e1x + alpha * ep1x;
-                double q1y = e1y + alpha * ep1y;
-                double q2x = e2x - alpha * ep2x;
-                double q2y = e2y - alpha * ep2y;
-
-                p.cubicTo((float) q1x,
-                        (float) q1y,
-                        (float) q2x,
-                        (float) q2y,
-                        (float) e2x,
-                        (float) e2y);
-                eta1 = eta2;
-                e1x = e2x;
-                e1y = e2y;
-                ep1x = ep2x;
-                ep1y = ep2y;
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java b/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
deleted file mode 100644
index 213e848..0000000
--- a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * Delegate overriding some methods of android.util.Xml
- *
- * Through the layoutlib_create tool, the original methods of Xml have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
- * around to map int to instance of the delegate.
- */
-public class Xml_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static XmlPullParser newPullParser() {
-        try {
-            return ParserFactory.instantiateParser(null);
-        } catch (XmlPullParserException e) {
-            throw new AssertionError();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
deleted file mode 100644
index 4445a22..0000000
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeWindow;
-import com.android.layoutlib.bridge.android.BridgeWindowSession;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.View.AttachInfo;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class AttachInfo_Accessor {
-
-    public static void setAttachInfo(View view) {
-        Context context = view.getContext();
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        Display display = wm.getDefaultDisplay();
-        ViewRootImpl root = new ViewRootImpl(context, display);
-        AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
-                display, root, new Handler(), null, context);
-        info.mHasWindowFocus = true;
-        info.mWindowVisibility = View.VISIBLE;
-        info.mInTouchMode = false; // this is so that we can display selections.
-        info.mHardwareAccelerated = false;
-        view.dispatchAttachedToWindow(info, 0);
-    }
-
-    public static void dispatchOnPreDraw(View view) {
-        view.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
-    }
-
-    public static void detachFromWindow(View view) {
-        if (view != null) {
-            view.dispatchDetachedFromWindow();
-        }
-    }
-
-    public static ViewRootImpl getRootView(View view) {
-        return view.mAttachInfo != null ? view.mAttachInfo.mViewRootImpl : null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
deleted file mode 100644
index b6e6ec0..0000000
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.MergeCookie;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
-import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-import android.widget.NumberPicker;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static com.android.SdkConstants.AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.BUTTON;
-import static com.android.SdkConstants.CHECKED_TEXT_VIEW;
-import static com.android.SdkConstants.CHECK_BOX;
-import static com.android.SdkConstants.EDIT_TEXT;
-import static com.android.SdkConstants.IMAGE_BUTTON;
-import static com.android.SdkConstants.IMAGE_VIEW;
-import static com.android.SdkConstants.MULTI_AUTO_COMPLETE_TEXT_VIEW;
-import static com.android.SdkConstants.RADIO_BUTTON;
-import static com.android.SdkConstants.SEEK_BAR;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TEXT_VIEW;
-import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
-
-/**
- * Custom implementation of {@link LayoutInflater} to handle custom views.
- */
-public final class BridgeInflater extends LayoutInflater {
-
-    private final LayoutlibCallback mLayoutlibCallback;
-    /**
-     * If true, the inflater will try to replace the framework widgets with the AppCompat versions.
-     * Ideally, this should be based on the activity being an AppCompat activity but since that is
-     * not trivial to check from layoutlib, we currently base the decision on the current theme
-     * being an AppCompat theme.
-     */
-    private boolean mLoadAppCompatViews;
-    /**
-     * This set contains the framework views that have an AppCompat version but failed to load.
-     * This might happen because not all widgets are contained in all versions of the support
-     * library.
-     * This will help us to avoid trying to load the AppCompat version multiple times if it
-     * doesn't exist.
-     */
-    private Set<String> mFailedAppCompatViews = new HashSet<>();
-    private boolean mIsInMerge = false;
-    private ResourceReference mResourceReference;
-    private Map<View, String> mOpenDrawerLayouts;
-
-    // Keep in sync with the same value in LayoutInflater.
-    private static final int[] ATTRS_THEME = new int[] {com.android.internal.R.attr.theme };
-
-    private static final String APPCOMPAT_WIDGET_PREFIX = "android.support.v7.widget.AppCompat";
-    /** List of platform widgets that have an AppCompat version */
-    private static final Set<String> APPCOMPAT_VIEWS = Collections.unmodifiableSet(
-            new HashSet<>(
-                    Arrays.asList(TEXT_VIEW, IMAGE_VIEW, BUTTON, EDIT_TEXT, SPINNER,
-                            IMAGE_BUTTON, CHECK_BOX, RADIO_BUTTON, CHECKED_TEXT_VIEW,
-                            AUTO_COMPLETE_TEXT_VIEW, MULTI_AUTO_COMPLETE_TEXT_VIEW, "RatingBar",
-                            SEEK_BAR)));
-
-    /**
-     * List of class prefixes which are tried first by default.
-     * <p/>
-     * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
-     */
-    private static final String[] sClassPrefixList = {
-        "android.widget.",
-        "android.webkit.",
-        "android.app."
-    };
-
-    public static String[] getClassPrefixList() {
-        return sClassPrefixList;
-    }
-
-    private BridgeInflater(LayoutInflater original, Context newContext) {
-        super(original, newContext);
-        newContext = getBaseContext(newContext);
-        if (newContext instanceof BridgeContext) {
-            mLayoutlibCallback = ((BridgeContext) newContext).getLayoutlibCallback();
-            mLoadAppCompatViews = ((BridgeContext) newContext).isAppCompatTheme();
-        } else {
-            mLayoutlibCallback = null;
-            mLoadAppCompatViews = false;
-        }
-    }
-
-    /**
-     * Instantiate a new BridgeInflater with an {@link LayoutlibCallback} object.
-     *
-     * @param context The Android application context.
-     * @param layoutlibCallback the {@link LayoutlibCallback} object.
-     */
-    public BridgeInflater(BridgeContext context, LayoutlibCallback layoutlibCallback) {
-        super(context);
-        mLayoutlibCallback = layoutlibCallback;
-        mConstructorArgs[0] = context;
-        mLoadAppCompatViews = context.isAppCompatTheme();
-    }
-
-    @Override
-    public View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
-        View view = null;
-
-        try {
-            if (mLoadAppCompatViews
-                    && APPCOMPAT_VIEWS.contains(name)
-                    && !mFailedAppCompatViews.contains(name)) {
-                // We are using an AppCompat theme so try to load the appcompat views
-                view = loadCustomView(APPCOMPAT_WIDGET_PREFIX + name, attrs, true);
-
-                if (view == null) {
-                    mFailedAppCompatViews.add(name); // Do not try this one anymore
-                }
-            }
-
-            if (view == null) {
-                // First try to find a class using the default Android prefixes
-                for (String prefix : sClassPrefixList) {
-                    try {
-                        view = createView(name, prefix, attrs);
-                        if (view != null) {
-                            break;
-                        }
-                    } catch (ClassNotFoundException e) {
-                        // Ignore. We'll try again using the base class below.
-                    }
-                }
-
-                // Next try using the parent loader. This will most likely only work for
-                // fully-qualified class names.
-                try {
-                    if (view == null) {
-                        view = super.onCreateView(name, attrs);
-                    }
-                } catch (ClassNotFoundException e) {
-                    // Ignore. We'll try again using the custom view loader below.
-                }
-            }
-
-            // Finally try again using the custom view loader
-            if (view == null) {
-                view = loadCustomView(name, attrs);
-            }
-        } catch (InflateException e) {
-            // Don't catch the InflateException below as that results in hiding the real cause.
-            throw e;
-        } catch (Exception e) {
-            // Wrap the real exception in a ClassNotFoundException, so that the calling method
-            // can deal with it.
-            throw new ClassNotFoundException("onCreateView", e);
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
-            boolean ignoreThemeAttr) {
-        View view = null;
-        if (name.equals("view")) {
-            // This is usually done by the superclass but this allows us catching the error and
-            // reporting something useful.
-            name = attrs.getAttributeValue(null, "class");
-
-            if (name == null) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to inflate view tag without " +
-                  "class attribute", null);
-                // We weren't able to resolve the view so we just pass a mock View to be able to
-                // continue rendering.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText("view");
-            }
-        }
-
-        try {
-            if (view == null) {
-                view = super.createViewFromTag(parent, name, context, attrs, ignoreThemeAttr);
-            }
-        } catch (InflateException e) {
-            // Creation of ContextThemeWrapper code is same as in the super method.
-            // Apply a theme wrapper, if allowed and one is specified.
-            if (!ignoreThemeAttr) {
-                final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-                final int themeResId = ta.getResourceId(0, 0);
-                if (themeResId != 0) {
-                    context = new ContextThemeWrapper(context, themeResId);
-                }
-                ta.recycle();
-            }
-            if (!(e.getCause() instanceof ClassNotFoundException)) {
-                // There is some unknown inflation exception in inflating a View that was found.
-                view = new MockView(context, attrs);
-                ((MockView) view).setText(name);
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null);
-            } else {
-                final Object lastContext = mConstructorArgs[0];
-                mConstructorArgs[0] = context;
-                // try to load the class from using the custom view loader
-                try {
-                    view = loadCustomView(name, attrs);
-                } catch (Exception e2) {
-                    // Wrap the real exception in an InflateException so that the calling
-                    // method can deal with it.
-                    InflateException exception = new InflateException();
-                    if (!e2.getClass().equals(ClassNotFoundException.class)) {
-                        exception.initCause(e2);
-                    } else {
-                        exception.initCause(e);
-                    }
-                    throw exception;
-                } finally {
-                    mConstructorArgs[0] = lastContext;
-                }
-            }
-        }
-
-        setupViewInContext(view, attrs);
-
-        return view;
-    }
-
-    @Override
-    public View inflate(int resource, ViewGroup root) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bridgeContext = (BridgeContext)context;
-
-            ResourceValue value = null;
-
-            @SuppressWarnings("deprecation")
-            Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
-            if (layoutInfo != null) {
-                value = bridgeContext.getRenderResources().getFrameworkResource(
-                        ResourceType.LAYOUT, layoutInfo.getSecond());
-            } else {
-                layoutInfo = mLayoutlibCallback.resolveResourceId(resource);
-
-                if (layoutInfo != null) {
-                    value = bridgeContext.getRenderResources().getProjectResource(
-                            ResourceType.LAYOUT, layoutInfo.getSecond());
-                }
-            }
-
-            if (value != null) {
-                File f = new File(value.getValue());
-                if (f.isFile()) {
-                    try {
-                        XmlPullParser parser = ParserFactory.create(f, true);
-
-                        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
-                                parser, bridgeContext, value.isFramework());
-
-                        return inflate(bridgeParser, root);
-                    } catch (Exception e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                                "Failed to parse file " + f.getAbsolutePath(), e, null);
-
-                        return null;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Instantiates the given view name and returns the instance. If the view doesn't exist, a
-     * MockView or null might be returned.
-     * @param name the custom view name
-     * @param attrs the {@link AttributeSet} to be passed to the view constructor
-     * @param silent if true, errors while loading the view won't be reported and, if the view
-     * doesn't exist, null will be returned.
-     */
-    private View loadCustomView(String name, AttributeSet attrs, boolean silent) throws Exception {
-        if (mLayoutlibCallback != null) {
-            // first get the classname in case it's not the node name
-            if (name.equals("view")) {
-                name = attrs.getAttributeValue(null, "class");
-                if (name == null) {
-                    return null;
-                }
-            }
-
-            mConstructorArgs[1] = attrs;
-
-            Object customView = silent ?
-                    mLayoutlibCallback.loadClass(name, mConstructorSignature, mConstructorArgs)
-                    : mLayoutlibCallback.loadView(name, mConstructorSignature, mConstructorArgs);
-
-            if (customView instanceof View) {
-                return (View)customView;
-            }
-        }
-
-        return null;
-    }
-
-    private View loadCustomView(String name, AttributeSet attrs) throws Exception {
-        return loadCustomView(name, attrs, false);
-    }
-
-    private void setupViewInContext(View view, AttributeSet attrs) {
-        Context context = getContext();
-        context = getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            BridgeContext bc = (BridgeContext) context;
-            // get the view key
-            Object viewKey = getViewKeyFromParser(attrs, bc, mResourceReference, mIsInMerge);
-            if (viewKey != null) {
-                bc.addViewKey(view, viewKey);
-            }
-            String scrollPosX = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollX");
-            if (scrollPosX != null && scrollPosX.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosX.substring(0, scrollPosX.length() - 2));
-                bc.setScrollXPos(view, value);
-            }
-            String scrollPosY = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY");
-            if (scrollPosY != null && scrollPosY.endsWith("px")) {
-                int value = Integer.parseInt(scrollPosY.substring(0, scrollPosY.length() - 2));
-                bc.setScrollYPos(view, value);
-            }
-            if (ReflectionUtils.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) {
-                Integer resourceId = null;
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_LIST_ITEM);
-                if (attrVal != null && !attrVal.isEmpty()) {
-                    ResourceValue resValue = bc.getRenderResources().findResValue(attrVal, false);
-                    if (resValue.isFramework()) {
-                        resourceId = Bridge.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    } else {
-                        resourceId = mLayoutlibCallback.getResourceId(resValue.getResourceType(),
-                                resValue.getName());
-                    }
-                }
-                if (resourceId == null) {
-                    resourceId = 0;
-                }
-                RecyclerViewUtil.setAdapter(view, bc, mLayoutlibCallback, resourceId);
-            } else if (ReflectionUtils.isInstanceOf(view, DrawerLayoutUtil.CN_DRAWER_LAYOUT)) {
-                String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
-                        BridgeConstants.ATTR_OPEN_DRAWER);
-                if (attrVal != null) {
-                    getDrawerLayoutMap().put(view, attrVal);
-                }
-            }
-            else if (view instanceof NumberPicker) {
-                NumberPicker numberPicker = (NumberPicker) view;
-                String minValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "minValue");
-                if (minValue != null) {
-                    numberPicker.setMinValue(Integer.parseInt(minValue));
-                }
-                String maxValue = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, "maxValue");
-                if (maxValue != null) {
-                    numberPicker.setMaxValue(Integer.parseInt(maxValue));
-                }
-            }
-            else if (view instanceof ImageView) {
-                ImageView img = (ImageView) view;
-                Drawable drawable = img.getDrawable();
-                if (drawable instanceof Animatable) {
-                    if (!((Animatable) drawable).isRunning()) {
-                        ((Animatable) drawable).start();
-                    }
-                }
-            }
-
-        }
-    }
-
-    public void setIsInMerge(boolean isInMerge) {
-        mIsInMerge = isInMerge;
-    }
-
-    public void setResourceReference(ResourceReference reference) {
-        mResourceReference = reference;
-    }
-
-    @Override
-    public LayoutInflater cloneInContext(Context newContext) {
-        return new BridgeInflater(this, newContext);
-    }
-
-    /*package*/ static Object getViewKeyFromParser(AttributeSet attrs, BridgeContext bc,
-            ResourceReference resourceReference, boolean isInMerge) {
-
-        if (!(attrs instanceof BridgeXmlBlockParser)) {
-            return null;
-        }
-        BridgeXmlBlockParser parser = ((BridgeXmlBlockParser) attrs);
-
-        // get the view key
-        Object viewKey = parser.getViewCookie();
-
-        if (viewKey == null) {
-            int currentDepth = parser.getDepth();
-
-            // test whether we are in an included file or in a adapter binding view.
-            BridgeXmlBlockParser previousParser = bc.getPreviousParser();
-            if (previousParser != null) {
-                // looks like we are inside an embedded layout.
-                // only apply the cookie of the calling node (<include>) if we are at the
-                // top level of the embedded layout. If there is a merge tag, then
-                // skip it and look for the 2nd level
-                int testDepth = isInMerge ? 2 : 1;
-                if (currentDepth == testDepth) {
-                    viewKey = previousParser.getViewCookie();
-                    // if we are in a merge, wrap the cookie in a MergeCookie.
-                    if (viewKey != null && isInMerge) {
-                        viewKey = new MergeCookie(viewKey);
-                    }
-                }
-            } else if (resourceReference != null && currentDepth == 1) {
-                // else if there's a resource reference, this means we are in an adapter
-                // binding case. Set the resource ref as the view cookie only for the top
-                // level view.
-                viewKey = resourceReference;
-            }
-        }
-
-        return viewKey;
-    }
-
-    public void postInflateProcess(View view) {
-        if (mOpenDrawerLayouts != null) {
-            String gravity = mOpenDrawerLayouts.get(view);
-            if (gravity != null) {
-                DrawerLayoutUtil.openDrawer(view, gravity);
-            }
-            mOpenDrawerLayouts.remove(view);
-        }
-    }
-
-    @NonNull
-    private Map<View, String> getDrawerLayoutMap() {
-        if (mOpenDrawerLayouts == null) {
-            mOpenDrawerLayouts = new HashMap<View, String>(4);
-        }
-        return mOpenDrawerLayouts;
-    }
-
-    public void onDoneInflation() {
-        if (mOpenDrawerLayouts != null) {
-            mOpenDrawerLayouts.clear();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
deleted file mode 100644
index 494ffa1..0000000
--- a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import java.lang.reflect.Field;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
- *
- * Through the layoutlib_create tool, the original  methods of Choreographer have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class Choreographer_Delegate {
-    static final AtomicReference<Choreographer> mInstance = new AtomicReference<Choreographer>();
-
-    @LayoutlibDelegate
-    public static Choreographer getInstance() {
-        if (mInstance.get() == null) {
-            mInstance.compareAndSet(null, Choreographer.getInstance_Original());
-        }
-
-        return mInstance.get();
-    }
-
-    @LayoutlibDelegate
-    public static float getRefreshRate() {
-        return 60.f;
-    }
-
-    @LayoutlibDelegate
-    static void scheduleVsyncLocked(Choreographer thisChoreographer) {
-        // do nothing
-    }
-
-    public static void doFrame(long frameTimeNanos) {
-        Choreographer thisChoreographer = Choreographer.getInstance();
-
-        thisChoreographer.mLastFrameTimeNanos = frameTimeNanos - thisChoreographer
-                .getFrameIntervalNanos();
-        thisChoreographer.mFrameInfo.markInputHandlingStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markAnimationsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
-
-        thisChoreographer.mFrameInfo.markPerformTraversalsStart();
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
-
-        thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
-    }
-
-    public static void dispose() {
-        try {
-            Field threadInstanceField = Choreographer.class.getDeclaredField("sThreadInstance");
-            threadInstanceField.setAccessible(true);
-            @SuppressWarnings("unchecked") ThreadLocal<Choreographer> threadInstance =
-                    (ThreadLocal<Choreographer>) threadInstanceField.get(null);
-            threadInstance.remove();
-        } catch (ReflectiveOperationException e) {
-            assert false;
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Unable to clear Choreographer memory.", e, null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
deleted file mode 100644
index 53dc821..0000000
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link Display}
- *
- * Through the layoutlib_create tool, the original  methods of Display have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class Display_Delegate {
-
-    @LayoutlibDelegate
-    static void updateDisplayInfoLocked(Display theDisplay) {
-        // do nothing
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java b/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
deleted file mode 100644
index e580ed0..0000000
--- a/tools/layoutlib/bridge/src/android/view/HandlerActionQueue_Delegate.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link HandlerActionQueue}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl.RunQueue have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class HandlerActionQueue_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void postDelayed(HandlerActionQueue thisQueue, Runnable action, long
-            delayMillis) {
-        // The actual HandlerActionQueue is never run and therefore never cleared. This method
-        // avoids runnables to be added to the RunQueue so they do not leak resources.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
deleted file mode 100644
index 15fd2ce..0000000
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.IRemoteCallback;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-
-import com.android.internal.app.IAssistScreenshotReceiver;
-import com.android.internal.os.IResultReceiver;
-import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.policy.IShortcutService;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
-/**
- * Basic implementation of {@link IWindowManager} so that {@link Display} (and
- * {@link Display_Delegate}) can return a valid instance.
- */
-public class IWindowManagerImpl implements IWindowManager {
-
-    private final Configuration mConfig;
-    private final DisplayMetrics mMetrics;
-    private final int mRotation;
-    private final boolean mHasNavigationBar;
-
-    public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
-            boolean hasNavigationBar) {
-        mConfig = config;
-        mMetrics = metrics;
-        mRotation = rotation;
-        mHasNavigationBar = hasNavigationBar;
-    }
-
-    // custom API.
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    // ---- implementation of IWindowManager that we care about ----
-
-    @Override
-    public int getDefaultDisplayRotation() throws RemoteException {
-        return mRotation;
-    }
-
-    @Override
-    public boolean hasNavigationBar() {
-        return mHasNavigationBar;
-    }
-
-    // ---- unused implementation of IWindowManager ----
-
-    @Override
-    public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearForcedDisplaySize(int displayId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void clearForcedDisplayDensityForUser(int displayId, int userId) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setOverscan(int displayId, int left, int top, int right, int bottom)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void closeSystemDialogs(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startFreezingScreen(int exitAnim, int enterAnim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void stopFreezingScreen() {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void executeAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void exitKeyguardSecurely(IOnKeyguardExitResult arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void freezeRotation(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getAnimationScale(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public float[] getAnimationScales() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPendingAppTransition() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public boolean inKeyguardRestrictedInputMode() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardLocked() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isKeyguardSecure() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isViewServerRunning() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public IWindowSession openSession(IWindowSessionCallback argn1, IInputMethodClient arg0,
-            IInputContext arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void overridePendingAppTransition(String arg0, int arg1, int arg2,
-            IRemoteCallback startedCallback) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
-            int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionClipReveal(int startX, int startY,
-            int startWidth, int startHeight) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
-            IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
-            int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
-            boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionInPlace(String packageName, int anim) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumbFuture(
-            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback startedCallback,
-            boolean scaleUp) throws RemoteException {
-
-    }
-
-    @Override
-    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
-            IRemoteCallback callback0, IRemoteCallback callback1, boolean scaleUp) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void prepareAppTransition(int arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void reenableKeyguard(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setAnimationScale(int arg0, float arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAnimationScales(float[] arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public float getCurrentAnimatorScale() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setEventDispatching(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setFocusedApp(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getInitialDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getBaseDisplaySize(int displayId, Point size) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplaySize(int displayId, int arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int getInitialDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public int getBaseDisplayDensity(int displayId) {
-        return -1;
-    }
-
-    @Override
-    public void setForcedDisplayDensityForUser(int displayId, int density, int userId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setForcedDisplayScalingMode(int displayId, int mode) {
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public int[] setNewDisplayOverrideConfiguration(Configuration arg0, int displayId)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setScreenCaptureDisabled(int userId, boolean disabled) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setStrictModeVisualIndicatorPreference(String arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void showStrictModeViolation(boolean arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean startViewServer(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void statusBarVisibilityChanged(int arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setRecentsVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setPipVisibility(boolean visible) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean stopViewServer() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void thawRotation() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public Configuration updateOrientationFromAppTokens(Configuration arg0, IBinder arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int watchRotation(IRotationWatcher arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void removeRotationWatcher(IRotationWatcher arg0) throws RemoteException {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getPreferredOptionsPanelGravity() throws RemoteException {
-        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    }
-
-    @Override
-    public void dismissKeyguard(IKeyguardDismissCallback callback) throws RemoteException {
-    }
-
-    @Override
-    public void setSwitchingUser(boolean switching) throws RemoteException {
-    }
-
-    @Override
-    public void lockNow(Bundle options) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean isSafeModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public boolean isRotationFrozen() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void enableScreenIfNeeded() throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean clearWindowContentFrameStats(IBinder token) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public WindowContentFrameStats getWindowContentFrameStats(IBinder token)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getDockedStackSide() throws RemoteException {
-        return 0;
-    }
-
-    @Override
-    public void setDockedStackResizing(boolean resizing) throws RemoteException {
-    }
-
-    @Override
-    public void endProlongedAnimations() {
-    }
-
-    @Override
-    public void registerDockedStackListener(IDockedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) throws RemoteException {
-    }
-
-    @Override
-    public void setResizeDimLayer(boolean visible, int targetStackId, float alpha)
-            throws RemoteException {
-    }
-
-    @Override
-    public void setDockedStackDividerTouchRegion(Rect touchableRegion) throws RemoteException {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
-    }
-
-    @Override
-    public void registerShortcutKey(long shortcutCode, IShortcutService service)
-        throws RemoteException {}
-
-    @Override
-    public void createInputConsumer(String name, InputChannel inputChannel)
-            throws RemoteException {}
-
-    @Override
-    public boolean destroyInputConsumer(String name) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public Bitmap screenshotWallpaper() throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public void enableSurfaceTrace(ParcelFileDescriptor fd) throws RemoteException {
-    }
-
-    @Override
-    public void disableSurfaceTrace() throws RemoteException {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
deleted file mode 100644
index cec6bb3..0000000
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.util.Xml;
-
-import java.io.IOException;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
- *
- * Through the layoutlib_create tool, the original  methods of LayoutInflater have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class LayoutInflater_Delegate {
-    private static final String TAG_MERGE = "merge";
-
-    private static final String ATTR_LAYOUT = "layout";
-
-    private static final int[] ATTRS_THEME = new int[] {
-            com.android.internal.R.attr.theme };
-
-    public static boolean sIsInInclude = false;
-
-    /**
-     * Recursive method used to descend down the xml hierarchy and instantiate
-     * views, instantiate their children, and then call onFinishInflate().
-     *
-     * This implementation just records the merge status before calling the default implementation.
-     */
-    @LayoutlibDelegate
-    /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
-            View parent, Context context, AttributeSet attrs, boolean finishInflate)
-            throws XmlPullParserException, IOException {
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(true);
-            }
-        }
-
-        // ---- START DEFAULT IMPLEMENTATION.
-
-        thisInflater.rInflate_Original(parser, parent, context, attrs, finishInflate);
-
-        // ---- END DEFAULT IMPLEMENTATION.
-
-        if (finishInflate == false) {
-            // this is a merge rInflate!
-            if (thisInflater instanceof BridgeInflater) {
-                ((BridgeInflater) thisInflater).setIsInMerge(false);
-            }
-        }
-    }
-
-    @LayoutlibDelegate
-    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser,
-            Context context, View parent, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-        int type;
-
-        if (parent instanceof ViewGroup) {
-            // Apply a theme wrapper, if requested. This is sort of a weird
-            // edge case, since developers think the <include> overwrites
-            // values in the AttributeSet of the included View. So, if the
-            // included View has a theme attribute, we'll need to ignore it.
-            final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
-            final int themeResId = ta.getResourceId(0, 0);
-            final boolean hasThemeOverride = themeResId != 0;
-            if (hasThemeOverride) {
-                context = new ContextThemeWrapper(context, themeResId);
-            }
-            ta.recycle();
-
-            // If the layout is pointing to a theme attribute, we have to
-            // massage the value to get a resource identifier out of it.
-            int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null || value.length() <= 0) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                    LayoutInflater.consumeChildElements(parser);
-                    return;
-                }
-
-                // Attempt to resolve the "?attr/name" string to an identifier.
-                layout = context.getResources().getIdentifier(value.substring(1), null, null);
-            }
-
-            // The layout might be referencing a theme attribute.
-            // ---- START CHANGES
-            if (layout != 0) {
-                final TypedValue tempValue = new TypedValue();
-                if (context.getTheme().resolveAttribute(layout, tempValue, true)) {
-                    layout = tempValue.resourceId;
-                }
-            }
-            // ---- END CHANGES
-
-            if (layout == 0) {
-                final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
-                if (value == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
-                            + " include tag: <include layout=\"@layout/layoutID\" />", null);
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout "
-                            + "reference. The layout ID " + value + " is not valid.", null);
-                }
-            } else {
-                final XmlResourceParser childParser =
-                    thisInflater.getContext().getResources().getLayout(layout);
-
-                try {
-                    final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
-
-                    while ((type = childParser.next()) != XmlPullParser.START_TAG &&
-                            type != XmlPullParser.END_DOCUMENT) {
-                        // Empty.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                                childParser.getPositionDescription() + ": No start tag found!",
-                                null);
-                        LayoutInflater.consumeChildElements(parser);
-                        return;
-                    }
-
-                    final String childName = childParser.getName();
-
-                    if (TAG_MERGE.equals(childName)) {
-                        // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, context, childAttrs, false);
-                    } else {
-                        final View view = thisInflater.createViewFromTag(parent, childName,
-                                context, childAttrs, hasThemeOverride);
-                        final ViewGroup group = (ViewGroup) parent;
-
-                        final TypedArray a = context.obtainStyledAttributes(
-                                attrs, com.android.internal.R.styleable.Include);
-                        final int id = a.getResourceId(
-                                com.android.internal.R.styleable.Include_id, View.NO_ID);
-                        final int visibility = a.getInt(
-                                com.android.internal.R.styleable.Include_visibility, -1);
-                        a.recycle();
-
-                        // We try to load the layout params set in the <include /> tag. If
-                        // they don't exist, we will rely on the layout params set in the
-                        // included XML file.
-                        // During a layoutparams generation, a runtime exception is thrown
-                        // if either layout_width or layout_height is missing. We catch
-                        // this exception and set localParams accordingly: true means we
-                        // successfully loaded layout params from the <include /> tag,
-                        // false means we need to rely on the included layout params.
-                        ViewGroup.LayoutParams params = null;
-                        try {
-                            // ---- START CHANGES
-                            sIsInInclude = true;
-                            // ---- END CHANGES
-
-                            params = group.generateLayoutParams(attrs);
-                        } catch (RuntimeException ignored) {
-                            // Ignore, just fail over to child attrs.
-                        } finally {
-                            // ---- START CHANGES
-                            sIsInInclude = false;
-                            // ---- END CHANGES
-                        }
-                        if (params == null) {
-                            params = group.generateLayoutParams(childAttrs);
-                        }
-                        view.setLayoutParams(params);
-
-                        // Inflate all children.
-                        thisInflater.rInflateChildren(childParser, view, childAttrs, true);
-
-                        if (id != View.NO_ID) {
-                            view.setId(id);
-                        }
-
-                        switch (visibility) {
-                            case 0:
-                                view.setVisibility(View.VISIBLE);
-                                break;
-                            case 1:
-                                view.setVisibility(View.INVISIBLE);
-                                break;
-                            case 2:
-                                view.setVisibility(View.GONE);
-                                break;
-                        }
-
-                        group.addView(view);
-                    }
-                } finally {
-                    childParser.close();
-                }
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "<include /> can only be used inside of a ViewGroup",
-                    null);
-        }
-
-        LayoutInflater.consumeChildElements(parser);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
deleted file mode 100644
index 08a97d6..0000000
--- a/tools/layoutlib/bridge/src/android/view/MenuInflater_Delegate.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.content.Context;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.AttributeSet;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuInflater}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of MenuInflater have been
- * replaced by calls to methods of the same name in this delegate class.
- * <p/>
- * The main purpose of the class is to get the view key from the menu xml parser and add it to
- * the menu item. The view key is used by the IDE to match the individual view elements to the
- * corresponding xml tag in the menu/layout file.
- * <p/>
- * For Menus, the views may be reused and the {@link MenuItem} is a better object to hold the
- * view key than the {@link MenuView.ItemView}. At the time of computation of the rest of {@link
- * ViewInfo}, we check the corresponding view key in the menu item for the view and add it
- */
-public class MenuInflater_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, MenuItem menuItem,
-            AttributeSet attrs) {
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            Context context = thisInflater.getContext();
-            context = BridgeContext.getBaseContext(context);
-            if (context instanceof BridgeContext) {
-                Object viewKey = BridgeInflater.getViewKeyFromParser(
-                        attrs, ((BridgeContext) context), null, false);
-                ((BridgeMenuItemImpl) menuItem).setViewCookie(viewKey);
-                return;
-            }
-        }
-        // This means that Bridge did not take over the instantiation of some object properly.
-        // This is most likely a bug in the LayoutLib code.
-        Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                "Action Bar Menu rendering may be incorrect.", null);
-
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void registerMenu(MenuInflater thisInflater, SubMenu subMenu,
-            AttributeSet parser) {
-        registerMenu(thisInflater, subMenu.getItem(), parser);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java b/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
deleted file mode 100644
index 4a5ea9b..0000000
--- a/tools/layoutlib/bridge/src/android/view/PointerIcon_Delegate.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-public class PointerIcon_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static void loadResource(PointerIcon icon, Context context, Resources resources,
-            int resourceId) {
-        // HACK: This bypasses the problem of having an enum resolved as a resourceId.
-        // PointerIcon would not be displayed by layoutlib anyway, so we always return the null
-        // icon.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
deleted file mode 100644
index aed85a7..0000000
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2015, 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.NonNull;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import com.android.layoutlib.bridge.shadowutil.SpotShadow;
-import com.android.layoutlib.bridge.shadowutil.ShadowBuffer;
-
-public class RectShadowPainter {
-
-    private static final float SHADOW_STRENGTH = 0.1f;
-    private static final int LIGHT_POINTS = 8;
-
-    private static final int QUADRANT_DIVIDED_COUNT = 8;
-
-    private static final int RAY_TRACING_RAYS = 180;
-    private static final int RAY_TRACING_LAYERS = 10;
-
-    public static void paintShadow(@NonNull Outline viewOutline, float elevation,
-            @NonNull Canvas canvas) {
-        Rect outline = new Rect();
-        if (!viewOutline.getRect(outline)) {
-            assert false : "Outline is not a rect shadow";
-            return;
-        }
-
-        if (elevation <= 0) {
-            // If elevation is 0, we don't need to paint the shadow
-            return;
-        }
-
-        Rect originCanvasRect = canvas.getClipBounds();
-        int saved = modifyCanvas(canvas);
-        if (saved == -1) {
-            return;
-        }
-        try {
-            float radius = viewOutline.getRadius();
-            if (radius <= 0) {
-                // We can not paint a shadow with radius 0
-                return;
-            }
-
-            // view's absolute position in this canvas.
-            int viewLeft = -originCanvasRect.left + outline.left;
-            int viewTop = -originCanvasRect.top + outline.top;
-            int viewRight = viewLeft + outline.width();
-            int viewBottom = viewTop + outline.height();
-
-            float[][] rectangleCoordinators = generateRectangleCoordinates(viewLeft, viewTop,
-                    viewRight, viewBottom, radius, elevation);
-
-            // TODO: get these values from resources.
-            float lightPosX = canvas.getWidth() / 2;
-            float lightPosY = 0;
-            float lightHeight = 1800;
-            float lightSize = 200;
-
-            paintGeometricShadow(rectangleCoordinators, lightPosX, lightPosY, lightHeight,
-                    lightSize, canvas);
-        } finally {
-            canvas.restoreToCount(saved);
-        }
-    }
-
-    private static int modifyCanvas(@NonNull Canvas canvas) {
-        Rect rect = canvas.getClipBounds();
-        canvas.translate(rect.left, rect.top);
-        return canvas.save();
-    }
-
-    @NonNull
-    private static float[][] generateRectangleCoordinates(float left, float top, float right,
-            float bottom, float radius, float elevation) {
-        left = left + radius;
-        top = top + radius;
-        right = right - radius;
-        bottom = bottom - radius;
-
-        final double RADIANS_STEP = 2 * Math.PI / 4 / QUADRANT_DIVIDED_COUNT;
-
-        float[][] ret = new float[QUADRANT_DIVIDED_COUNT * 4][3];
-
-        int points = 0;
-        // left-bottom points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // left-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (left + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-top points
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right + radius - radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (top + radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-        // right-bottom point
-        for (int i = 0; i < QUADRANT_DIVIDED_COUNT; i++) {
-            ret[points][0] = (float) (right - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][1] = (float) (bottom - radius + radius * Math.cos(RADIANS_STEP * i));
-            ret[points][2] = elevation;
-            points++;
-        }
-
-        return ret;
-    }
-
-    private static void paintGeometricShadow(@NonNull float[][] coordinates, float lightPosX,
-            float lightPosY, float lightHeight, float lightSize, Canvas canvas) {
-        if (canvas == null || canvas.getWidth() == 0 || canvas.getHeight() == 0) {
-            return;
-        }
-
-        // The polygon of shadow (same as the original item)
-        float[] shadowPoly = new float[coordinates.length * 3];
-        for (int i = 0; i < coordinates.length; i++) {
-            shadowPoly[i * 3 + 0] = coordinates[i][0];
-            shadowPoly[i * 3 + 1] = coordinates[i][1];
-            shadowPoly[i * 3 + 2] = coordinates[i][2];
-        }
-
-        // TODO: calculate the ambient shadow and mix with Spot shadow.
-
-        // Calculate the shadow of SpotLight
-        float[] light = SpotShadow.calculateLight(lightSize, LIGHT_POINTS, lightPosX,
-                lightPosY, lightHeight);
-
-        int stripSize = 3 * SpotShadow.getStripSize(RAY_TRACING_RAYS, RAY_TRACING_LAYERS);
-        if (stripSize < 9) {
-            return;
-        }
-        float[] strip = new float[stripSize];
-        SpotShadow.calcShadow(light, LIGHT_POINTS, shadowPoly, coordinates.length, RAY_TRACING_RAYS,
-                RAY_TRACING_LAYERS, 1f, strip);
-
-        ShadowBuffer buff = new ShadowBuffer(canvas.getWidth(), canvas.getHeight());
-        buff.generateTriangles(strip, SHADOW_STRENGTH);
-        buff.draw(canvas);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
deleted file mode 100644
index 152878b..0000000
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Matrix;
-
-import libcore.util.NativeAllocationRegistry_Delegate;
-
-/**
- * Delegate implementing the native methods of {@link RenderNode}
- * <p/>
- * Through the layoutlib_create tool, some native methods of RenderNode have been replaced by calls
- * to methods of the same name in this delegate class.
- *
- * @see DelegateManager
- */
-public class RenderNode_Delegate {
-
-
-    // ---- delegate manager ----
-    private static final DelegateManager<RenderNode_Delegate> sManager =
-            new DelegateManager<RenderNode_Delegate>(RenderNode_Delegate.class);
-    private static long sFinalizer = -1;
-
-    private float mLift;
-    private float mTranslationX;
-    private float mTranslationY;
-    private float mTranslationZ;
-    private float mRotation;
-    private float mScaleX = 1;
-    private float mScaleY = 1;
-    private float mPivotX;
-    private float mPivotY;
-    private boolean mPivotExplicitlySet;
-    private int mLeft;
-    private int mRight;
-    private int mTop;
-    private int mBottom;
-    @SuppressWarnings("UnusedDeclaration")
-    private String mName;
-
-    @LayoutlibDelegate
-    /*package*/ static long nCreate(String name) {
-        RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
-        renderNodeDelegate.mName = name;
-        return sManager.addNewDelegate(renderNodeDelegate);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long nGetNativeFinalizer() {
-        synchronized (RenderNode_Delegate.class) {
-            if (sFinalizer == -1) {
-                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
-            }
-        }
-        return sFinalizer;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetElevation(long renderNode, float lift) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLift != lift) {
-            delegate.mLift = lift;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetElevation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mLift;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationX != translationX) {
-            delegate.mTranslationX = translationX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationY != translationY) {
-            delegate.mTranslationY = translationY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationY;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTranslationZ != translationZ) {
-            delegate.mTranslationZ = translationZ;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetTranslationZ(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mTranslationZ;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRotation != rotation) {
-            delegate.mRotation = rotation;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetRotation(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mRotation;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
-        outMatrix.reset();
-        if (renderNode != null) {
-            float rotation = renderNode.getRotation();
-            float translationX = renderNode.getTranslationX();
-            float translationY = renderNode.getTranslationY();
-            float pivotX = renderNode.getPivotX();
-            float pivotY = renderNode.getPivotY();
-            float scaleX = renderNode.getScaleX();
-            float scaleY = renderNode.getScaleY();
-
-            outMatrix.setTranslate(translationX, translationY);
-            outMatrix.preRotate(rotation, pivotX, pivotY);
-            outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeft(long renderNode, int left) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mLeft != left) {
-            delegate.mLeft = left;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetTop(long renderNode, int top) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mTop != top) {
-            delegate.mTop = top;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetRight(long renderNode, int right) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mRight != right) {
-            delegate.mRight = right;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mBottom != bottom) {
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
-            int bottom) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
-                .mRight != right || delegate.mBottom != bottom)) {
-            delegate.mLeft = left;
-            delegate.mTop = top;
-            delegate.mRight = right;
-            delegate.mBottom = bottom;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        return delegate != null && delegate.mPivotExplicitlySet;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotX = pivotX;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotX;
-            } else {
-                return (delegate.mRight - delegate.mLeft) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            delegate.mPivotY = pivotY;
-            delegate.mPivotExplicitlySet = true;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetPivotY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            if (delegate.mPivotExplicitlySet) {
-                return delegate.mPivotY;
-            } else {
-                return (delegate.mBottom - delegate.mTop) / 2.0f;
-            }
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleX != scaleX) {
-            delegate.mScaleX = scaleX;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleX(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleX;
-        }
-        return 0f;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null && delegate.mScaleY != scaleY) {
-            delegate.mScaleY = scaleY;
-            return true;
-        }
-        return false;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static float nGetScaleY(long renderNode) {
-        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
-        if (delegate != null) {
-            return delegate.mScaleY;
-        }
-        return 0f;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java b/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
deleted file mode 100644
index f09fffd..0000000
--- a/tools/layoutlib/bridge/src/android/view/ShadowPainter.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.NonNull;
-
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBufferInt;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-public class ShadowPainter {
-
-    /**
-     * Adds a drop shadow to a semi-transparent image (of an arbitrary shape) and returns it as a
-     * new image. This method attempts to mimic the same visual characteristics as the rectangular
-     * shadow painting methods in this class, {@link #createRectangularDropShadow(java.awt.image.BufferedImage)}
-     * and {@link #createSmallRectangularDropShadow(java.awt.image.BufferedImage)}.
-     * <p/>
-     * If shadowSize is less or equals to 1, no shadow will be painted and the source image will be
-     * returned instead.
-     *
-     * @param source the source image
-     * @param shadowSize the size of the shadow, normally {@link #SHADOW_SIZE or {@link
-     * #SMALL_SHADOW_SIZE}}
-     *
-     * @return an image with the shadow painted in or the source image if shadowSize <= 1
-     */
-    @NonNull
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize) {
-        shadowSize /= 2; // make shadow size have the same meaning as in the other shadow paint methods in this class
-
-        return createDropShadow(source, shadowSize, 0.7f, 0);
-    }
-
-    /**
-     * Creates a drop shadow of a given image and returns a new image which shows the input image on
-     * top of its drop shadow.
-     * <p/>
-     * <b>NOTE: If the shape is rectangular and opaque, consider using {@link
-     * #drawRectangleShadow(Graphics2D, int, int, int, int)} instead.</b>
-     *
-     * @param source the source image to be shadowed
-     * @param shadowSize the size of the shadow in pixels
-     * @param shadowOpacity the opacity of the shadow, with 0=transparent and 1=opaque
-     * @param shadowRgb the RGB int to use for the shadow color
-     *
-     * @return a new image with the source image on top of its shadow when shadowSize > 0 or the
-     * source image otherwise
-     */
-    @SuppressWarnings({"SuspiciousNameCombination", "UnnecessaryLocalVariable"})  // Imported code
-    public static BufferedImage createDropShadow(BufferedImage source, int shadowSize,
-            float shadowOpacity, int shadowRgb) {
-        if (shadowSize <= 0) {
-            return source;
-        }
-
-        // This code is based on
-        //      http://www.jroller.com/gfx/entry/non_rectangular_shadow
-
-        BufferedImage image;
-        int width = source.getWidth();
-        int height = source.getHeight();
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE,
-                BufferedImage.TYPE_INT_ARGB);
-
-        Graphics2D g2 = image.createGraphics();
-        g2.drawImage(image, shadowSize, shadowSize, null);
-
-        int dstWidth = image.getWidth();
-        int dstHeight = image.getHeight();
-
-        int left = (shadowSize - 1) >> 1;
-        int right = shadowSize - left;
-        int xStart = left;
-        int xStop = dstWidth - right;
-        int yStart = left;
-        int yStop = dstHeight - right;
-
-        shadowRgb &= 0x00FFFFFF;
-
-        int[] aHistory = new int[shadowSize];
-        int historyIdx;
-
-        int aSum;
-
-        int[] dataBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
-        int lastPixelOffset = right * dstWidth;
-        float sumDivider = shadowOpacity / shadowSize;
-
-        // horizontal pass
-        for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y * dstWidth) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int x = 0; x < shadowSize; x++, bufferOffset++) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[x] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= right;
-
-            for (int x = xStart; x < xStop; x++, bufferOffset++) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + right] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-        // vertical pass
-        for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
-            aSum = 0;
-            historyIdx = 0;
-            for (int y = 0; y < shadowSize; y++, bufferOffset += dstWidth) {
-                int a = dataBuffer[bufferOffset] >>> 24;
-                aHistory[y] = a;
-                aSum += a;
-            }
-
-            bufferOffset -= lastPixelOffset;
-
-            for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
-                int a = (int) (aSum * sumDivider);
-                dataBuffer[bufferOffset] = a << 24 | shadowRgb;
-
-                // subtract the oldest pixel from the sum
-                aSum -= aHistory[historyIdx];
-
-                // get the latest pixel
-                a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
-                aHistory[historyIdx] = a;
-                aSum += a;
-
-                if (++historyIdx >= shadowSize) {
-                    historyIdx -= shadowSize;
-                }
-            }
-        }
-
-        g2.drawImage(source, null, 0, 0);
-        g2.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a rectangular drop shadow (of size {@link #SHADOW_SIZE} by {@link #SHADOW_SIZE} around
-     * the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-        BufferedImage image;
-        image = new BufferedImage(width + SHADOW_SIZE, height + SHADOW_SIZE, type);
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a small rectangular drop shadow (of size {@link #SMALL_SHADOW_SIZE} by {@link
-     * #SMALL_SHADOW_SIZE} around the given source and returns a new image with both combined
-     *
-     * @param source the source image
-     *
-     * @return the source image with a drop shadow on the bottom and right
-     */
-    @SuppressWarnings("UnusedDeclaration")
-    public static BufferedImage createSmallRectangularDropShadow(BufferedImage source) {
-        int type = source.getType();
-        if (type == BufferedImage.TYPE_CUSTOM) {
-            type = BufferedImage.TYPE_INT_ARGB;
-        }
-
-        int width = source.getWidth();
-        int height = source.getHeight();
-
-        BufferedImage image;
-        image = new BufferedImage(width + SMALL_SHADOW_SIZE, height + SMALL_SHADOW_SIZE, type);
-
-        Graphics2D g = image.createGraphics();
-        g.drawImage(source, 0, 0, null);
-        drawSmallRectangleShadow(image, 0, 0, width, height);
-        g.dispose();
-
-        return image;
-    }
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics. The size of the shadow is {@link #SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics. The size of the shadow is {@link #SMALL_SHADOW_SIZE}.
-     *
-     * @param image the image to draw the shadow into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(BufferedImage image,
-            int x, int y, int width, int height) {
-        Graphics2D gc = image.createGraphics();
-        try {
-            drawSmallRectangleShadow(gc, x, y, width, height);
-        } finally {
-            gc.dispose();
-        }
-    }
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SHADOW_SIZE = 20; // DO NOT EDIT. This corresponds to bitmap graphics
-
-    /**
-     * The width and height of the drop shadow painted by
-     * {@link #drawSmallRectangleShadow(Graphics2D, int, int, int, int)}
-     */
-    public static final int SMALL_SHADOW_SIZE = 10; // DO NOT EDIT. Corresponds to bitmap graphics
-
-    /**
-     * Draws a drop shadow for the given rectangle into the given context. It will not draw anything
-     * if the rectangle is smaller than a minimum determined by the assets used to draw the shadow
-     * graphics.
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawRectangleShadow(Graphics2D gc, int x, int y, int width, int height) {
-        assert ShadowBottomLeft != null;
-        assert ShadowBottomRight.getWidth(null) == SHADOW_SIZE;
-        assert ShadowBottomRight.getHeight(null) == SHADOW_SIZE;
-
-        int blWidth = ShadowBottomLeft.getWidth(null);
-        int trHeight = ShadowTopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(ShadowBottomLeft, x - ShadowBottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(ShadowBottomRight, x + width, y + height, null);
-        gc.drawImage(ShadowTopRight, x + width, y, null);
-        gc.drawImage(ShadowTopLeft, x - ShadowTopLeft.getWidth(null), y, null);
-        gc.drawImage(ShadowBottom,
-                x, y + height, x + width, y + height + ShadowBottom.getHeight(null),
-                0, 0, ShadowBottom.getWidth(null), ShadowBottom.getHeight(null), null);
-        gc.drawImage(ShadowRight,
-                x + width, y + ShadowTopRight.getHeight(null), x + width + ShadowRight.getWidth(null), y + height,
-                0, 0, ShadowRight.getWidth(null), ShadowRight.getHeight(null), null);
-        gc.drawImage(ShadowLeft,
-                x - ShadowLeft.getWidth(null), y + ShadowTopLeft.getHeight(null), x, y + height,
-                0, 0, ShadowLeft.getWidth(null), ShadowLeft.getHeight(null), null);
-    }
-
-    /**
-     * Draws a small drop shadow for the given rectangle into the given context. It will not draw
-     * anything if the rectangle is smaller than a minimum determined by the assets used to draw the
-     * shadow graphics.
-     * <p/>
-     *
-     * @param gc the graphics context to draw into
-     * @param x the left coordinate of the left hand side of the rectangle
-     * @param y the top coordinate of the top of the rectangle
-     * @param width the width of the rectangle
-     * @param height the height of the rectangle
-     */
-    public static void drawSmallRectangleShadow(Graphics2D gc, int x, int y, int width,
-            int height) {
-        assert Shadow2BottomLeft != null;
-        assert Shadow2TopRight != null;
-        assert Shadow2BottomRight.getWidth(null) == SMALL_SHADOW_SIZE;
-        assert Shadow2BottomRight.getHeight(null) == SMALL_SHADOW_SIZE;
-
-        int blWidth = Shadow2BottomLeft.getWidth(null);
-        int trHeight = Shadow2TopRight.getHeight(null);
-        if (width < blWidth) {
-            return;
-        }
-        if (height < trHeight) {
-            return;
-        }
-
-        gc.drawImage(Shadow2BottomLeft, x - Shadow2BottomLeft.getWidth(null), y + height, null);
-        gc.drawImage(Shadow2BottomRight, x + width, y + height, null);
-        gc.drawImage(Shadow2TopRight, x + width, y, null);
-        gc.drawImage(Shadow2TopLeft, x - Shadow2TopLeft.getWidth(null), y, null);
-        gc.drawImage(Shadow2Bottom,
-                x, y + height, x + width, y + height + Shadow2Bottom.getHeight(null),
-                0, 0, Shadow2Bottom.getWidth(null), Shadow2Bottom.getHeight(null), null);
-        gc.drawImage(Shadow2Right,
-                x + width, y + Shadow2TopRight.getHeight(null), x + width + Shadow2Right.getWidth(null), y + height,
-                0, 0, Shadow2Right.getWidth(null), Shadow2Right.getHeight(null), null);
-        gc.drawImage(Shadow2Left,
-                x - Shadow2Left.getWidth(null), y + Shadow2TopLeft.getHeight(null), x, y + height,
-                0, 0, Shadow2Left.getWidth(null), Shadow2Left.getHeight(null), null);
-    }
-
-    private static Image loadIcon(String name) {
-        InputStream inputStream = ShadowPainter.class.getResourceAsStream(name);
-        if (inputStream == null) {
-            throw new RuntimeException("Unable to load image for shadow: " + name);
-        }
-        try {
-            return ImageIO.read(inputStream);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to load image for shadow:" + name, e);
-        } finally {
-            try {
-                inputStream.close();
-            } catch (IOException e) {
-                // ignore.
-            }
-        }
-    }
-
-    // Shadow graphics. This was generated by creating a drop shadow in
-    // Gimp, using the parameters x offset=10, y offset=10, blur radius=10,
-    // (for the small drop shadows x offset=10, y offset=10, blur radius=10)
-    // color=black, and opacity=51. These values attempt to make a shadow
-    // that is legible both for dark and light themes, on top of the
-    // canvas background (rgb(150,150,150). Darker shadows would tend to
-    // blend into the foreground for a dark holo screen, and lighter shadows
-    // would be hard to spot on the canvas background. If you make adjustments,
-    // make sure to check the shadow with both dark and light themes.
-    //
-    // After making the graphics, I cut out the top right, bottom left
-    // and bottom right corners as 20x20 images, and these are reproduced by
-    // painting them in the corresponding places in the target graphics context.
-    // I then grabbed a single horizontal gradient line from the middle of the
-    // right edge,and a single vertical gradient line from the bottom. These
-    // are then painted scaled/stretched in the target to fill the gaps between
-    // the three corner images.
-    //
-    // Filenames: bl=bottom left, b=bottom, br=bottom right, r=right, tr=top right
-
-    // Normal Drop Shadow
-    private static final Image ShadowBottom = loadIcon("/icons/shadow-b.png");
-    private static final Image ShadowBottomLeft = loadIcon("/icons/shadow-bl.png");
-    private static final Image ShadowBottomRight = loadIcon("/icons/shadow-br.png");
-    private static final Image ShadowRight = loadIcon("/icons/shadow-r.png");
-    private static final Image ShadowTopRight = loadIcon("/icons/shadow-tr.png");
-    private static final Image ShadowTopLeft = loadIcon("/icons/shadow-tl.png");
-    private static final Image ShadowLeft = loadIcon("/icons/shadow-l.png");
-
-    // Small Drop Shadow
-    private static final Image Shadow2Bottom = loadIcon("/icons/shadow2-b.png");
-    private static final Image Shadow2BottomLeft = loadIcon("/icons/shadow2-bl.png");
-    private static final Image Shadow2BottomRight = loadIcon("/icons/shadow2-br.png");
-    private static final Image Shadow2Right = loadIcon("/icons/shadow2-r.png");
-    private static final Image Shadow2TopRight = loadIcon("/icons/shadow2-tr.png");
-    private static final Image Shadow2TopLeft = loadIcon("/icons/shadow2-tl.png");
-    private static final Image Shadow2Left = loadIcon("/icons/shadow2-l.png");
-}
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
deleted file mode 100644
index ebb2af4..0000000
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.util.AttributeSet;
-
-/**
- * Mock version of the SurfaceView.
- * Only non override public methods from the real SurfaceView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- *
- * TODO: generate automatically.
- *
- */
-public class SurfaceView extends MockView {
-
-    public SurfaceView(Context context) {
-        this(context, null);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs) {
-        this(context, attrs , 0);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public boolean gatherTransparentRegion(Region region) {
-      return false;
-    }
-
-    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-    }
-
-    public void setZOrderOnTop(boolean onTop) {
-    }
-
-    public void setSecure(boolean isSecure) {
-    }
-
-    public SurfaceHolder getHolder() {
-        return mSurfaceHolder;
-    }
-
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-
-        @Override
-        public boolean isCreating() {
-            return false;
-        }
-
-        @Override
-        public void addCallback(Callback callback) {
-        }
-
-        @Override
-        public void removeCallback(Callback callback) {
-        }
-
-        @Override
-        public void setFixedSize(int width, int height) {
-        }
-
-        @Override
-        public void setSizeFromLayout() {
-        }
-
-        @Override
-        public void setFormat(int format) {
-        }
-
-        @Override
-        public void setType(int type) {
-        }
-
-        @Override
-        public void setKeepScreenOn(boolean screenOn) {
-        }
-
-        @Override
-        public Canvas lockCanvas() {
-            return null;
-        }
-
-        @Override
-        public Canvas lockCanvas(Rect dirty) {
-            return null;
-        }
-
-        @Override
-        public void unlockCanvasAndPost(Canvas canvas) {
-        }
-
-        @Override
-        public Surface getSurface() {
-            return null;
-        }
-
-        @Override
-        public Rect getSurfaceFrame() {
-            return null;
-        }
-    };
-}
-
diff --git a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
deleted file mode 100644
index c3533e0..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewConfiguration_Accessor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class ViewConfiguration_Accessor {
-
-    public static void clearConfigurations() {
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration.sConfigurations.clear();
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
deleted file mode 100644
index 23caaf8..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.resources.Density;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Outline;
-import android.graphics.Path_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region.Op;
-import android.view.animation.Transformation;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewGroup}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of ViewGroup have been replaced by calls
- * to methods of the same name in this delegate class.
- */
-public class ViewGroup_Delegate {
-
-    /**
-     * Overrides the original drawChild call in ViewGroup to draw the shadow.
-     */
-    @LayoutlibDelegate
-    /*package*/ static boolean drawChild(ViewGroup thisVG, Canvas canvas, View child,
-            long drawingTime) {
-        if (child.getZ() > thisVG.getZ()) {
-            // The background's bounds are set lazily. Make sure they are set correctly so that
-            // the outline obtained is correct.
-            child.setBackgroundBounds();
-            ViewOutlineProvider outlineProvider = child.getOutlineProvider();
-            Outline outline = child.mAttachInfo.mTmpOutline;
-            outlineProvider.getOutline(child, outline);
-            if (outline.mPath != null || (outline.mRect != null && !outline.mRect.isEmpty())) {
-                int restoreTo = transformCanvas(thisVG, canvas, child);
-                drawShadow(thisVG, canvas, child, outline);
-                canvas.restoreToCount(restoreTo);
-            }
-        }
-        return thisVG.drawChild_Original(canvas, child, drawingTime);
-    }
-
-    private static void drawShadow(ViewGroup parent, Canvas canvas, View child,
-            Outline outline) {
-        float elevation = getElevation(child, parent);
-        if(outline.mMode == Outline.MODE_ROUND_RECT && outline.mRect != null) {
-            RectShadowPainter.paintShadow(outline, elevation, canvas);
-            return;
-        }
-        BufferedImage shadow = null;
-        if (outline.mPath != null) {
-            shadow = getPathShadow(outline, canvas, elevation);
-        }
-        if (shadow == null) {
-            return;
-        }
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(shadow, false,
-                Density.getEnum(canvas.getDensity()));
-        Rect clipBounds = canvas.getClipBounds();
-        Rect newBounds = new Rect(clipBounds);
-        newBounds.inset((int)-elevation, (int)-elevation);
-        canvas.clipRect(newBounds, Op.REPLACE);
-        canvas.drawBitmap(bitmap, 0, 0, null);
-        canvas.clipRect(clipBounds, Op.REPLACE);
-    }
-
-    private static float getElevation(View child, ViewGroup parent) {
-        return child.getZ() - parent.getZ();
-    }
-
-    private static BufferedImage getPathShadow(Outline outline, Canvas canvas, float elevation) {
-        Rect clipBounds = canvas.getClipBounds();
-        if (clipBounds.isEmpty()) {
-          return null;
-        }
-        BufferedImage image = new BufferedImage(clipBounds.width(), clipBounds.height(),
-                BufferedImage.TYPE_INT_ARGB);
-        Graphics2D graphics = image.createGraphics();
-        graphics.draw(Path_Delegate.getDelegate(outline.mPath.mNativePath).getJavaShape());
-        graphics.dispose();
-        return ShadowPainter.createDropShadow(image, (int) elevation);
-    }
-
-    // Copied from android.view.View#draw(Canvas, ViewGroup, long) and removed code paths
-    // which were never taken. Ideally, we should hook up the shadow code in the same method so
-    // that we don't have to transform the canvas twice.
-    private static int transformCanvas(ViewGroup thisVG, Canvas canvas, View child) {
-        final int restoreTo = canvas.save();
-        final boolean childHasIdentityMatrix = child.hasIdentityMatrix();
-        int flags = thisVG.mGroupFlags;
-        Transformation transformToApply = null;
-        boolean concatMatrix = false;
-        if ((flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
-            final Transformation t = thisVG.getChildTransformation();
-            final boolean hasTransform = thisVG.getChildStaticTransformation(child, t);
-            if (hasTransform) {
-                final int transformType = t.getTransformationType();
-                transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
-                concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
-            }
-        }
-        concatMatrix |= childHasIdentityMatrix;
-
-        child.computeScroll();
-        int sx = child.mScrollX;
-        int sy = child.mScrollY;
-
-        canvas.translate(child.mLeft - sx, child.mTop - sy);
-        float alpha = child.getAlpha() * child.getTransitionAlpha();
-
-        if (transformToApply != null || alpha < 1 || !childHasIdentityMatrix) {
-            if (transformToApply != null || !childHasIdentityMatrix) {
-                int transX = -sx;
-                int transY = -sy;
-
-                if (transformToApply != null) {
-                    if (concatMatrix) {
-                        // Undo the scroll translation, apply the transformation matrix,
-                        // then redo the scroll translate to get the correct result.
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(transformToApply.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                    if (!childHasIdentityMatrix) {
-                        canvas.translate(-transX, -transY);
-                        canvas.concat(child.getMatrix());
-                        canvas.translate(transX, transY);
-                    }
-                }
-
-            }
-        }
-        return restoreTo;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
deleted file mode 100644
index 0e15b97..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Accessor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-/**
- * Accessor to allow layoutlib to call {@link ViewRootImpl#dispatchApplyInsets} directly.
- */
-public class ViewRootImpl_Accessor {
-    public static void dispatchApplyInsets(ViewRootImpl viewRoot, View host) {
-        viewRoot.dispatchApplyInsets(host);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
deleted file mode 100644
index 14b84ef..0000000
--- a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl}
- *
- * Through the layoutlib_create tool, the original  methods of ViewRootImpl have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ViewRootImpl_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInTouchMode() {
-        return false; // this allows displaying selection.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
deleted file mode 100644
index 408ec54..0000000
--- a/tools/layoutlib/bridge/src/android/view/View_Delegate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.IBinder;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link View}
- *
- * Through the layoutlib_create tool, the original  methods of View have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class View_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static boolean isInEditMode(View thisView) {
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static IBinder getWindowToken(View thisView) {
-        Context baseContext = BridgeContext.getBaseContext(thisView.getContext());
-        if (baseContext instanceof BridgeContext) {
-            return ((BridgeContext) baseContext).getBinder();
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowCallback.java b/tools/layoutlib/bridge/src/android/view/WindowCallback.java
deleted file mode 100644
index 1ea8a9f..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowCallback.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.Nullable;
-import android.view.ActionMode.Callback;
-import android.view.WindowManager.LayoutParams;
-import android.view.accessibility.AccessibilityEvent;
-
-import java.util.List;
-
-/**
- * An empty implementation of {@link Window.Callback} that always returns null/false.
- */
-public class WindowCallback implements Window.Callback {
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTrackballEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchGenericMotionEvent(MotionEvent event) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        return false;
-    }
-
-    @Override
-    public View onCreatePanelView(int featureId) {
-        return null;
-    }
-
-    @Override
-    public boolean onCreatePanelMenu(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onPreparePanel(int featureId, View view, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuOpened(int featureId, Menu menu) {
-        return false;
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        return false;
-    }
-
-    @Override
-    public void onWindowAttributesChanged(LayoutParams attrs) {
-
-    }
-
-    @Override
-    public void onContentChanged() {
-
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-
-    }
-
-    @Override
-    public void onPanelClosed(int featureId, Menu menu) {
-
-    }
-
-    @Override
-    public boolean onSearchRequested(SearchEvent searchEvent) {
-        return onSearchRequested();
-    }
-
-    @Override
-    public boolean onSearchRequested() {
-        return false;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback) {
-        return null;
-    }
-
-    @Override
-    public ActionMode onWindowStartingActionMode(Callback callback, int type) {
-        return null;
-    }
-
-    @Override
-    public void onActionModeStarted(ActionMode mode) {
-
-    }
-
-    @Override
-    public void onActionModeFinished(ActionMode mode) {
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
deleted file mode 100644
index 2606e55..0000000
--- a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of
- * {@link WindowManagerGlobal}
- *
- * Through the layoutlib_create tool, the original  methods of WindowManagerGlobal have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-public class WindowManagerGlobal_Delegate {
-
-    private static IWindowManager sService;
-
-    @LayoutlibDelegate
-    public static IWindowManager getWindowManagerService() {
-        return sService;
-    }
-
-    // ---- internal implementation stuff ----
-
-    public static void setWindowManagerService(IWindowManager service) {
-        sService = service;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java b/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
deleted file mode 100644
index 11cb046..0000000
--- a/tools/layoutlib/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.os.Handler;
-import android.view.IWindow;
-import android.view.View;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
- * Such events are generated when something notable happens in the user interface,
- * for example an {@link android.app.Activity} starts, the focus or selection of a
- * {@link android.view.View} changes etc. Parties interested in handling accessibility
- * events implement and register an accessibility service which extends
- * {@code android.accessibilityservice.AccessibilityService}.
- *
- * @see AccessibilityEvent
- * @see android.content.Context#getSystemService
- */
-@SuppressWarnings("UnusedDeclaration")
-public final class AccessibilityManager {
-
-    private static AccessibilityManager sInstance = new AccessibilityManager(null, null, 0);
-
-
-    /**
-     * Listener for the accessibility state.
-     */
-    public interface AccessibilityStateChangeListener {
-
-        /**
-         * Called back on change in the accessibility state.
-         *
-         * @param enabled Whether accessibility is enabled.
-         */
-        public void onAccessibilityStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system touch exploration state. To listen for changes to
-     * the touch exploration state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addTouchExplorationStateChangeListener}.
-     */
-    public interface TouchExplorationStateChangeListener {
-
-        /**
-         * Called when the touch exploration enabled state changes.
-         *
-         * @param enabled Whether touch exploration is enabled.
-         */
-        public void onTouchExplorationStateChanged(boolean enabled);
-    }
-
-    /**
-     * Listener for the system high text contrast state. To listen for changes to
-     * the high text contrast state on the device, implement this interface and
-     * register it with the system by calling
-     * {@link #addHighTextContrastStateChangeListener}.
-     */
-    public interface HighTextContrastChangeListener {
-
-        /**
-         * Called when the high text contrast enabled state changes.
-         *
-         * @param enabled Whether high text contrast is enabled.
-         */
-        public void onHighTextContrastStateChanged(boolean enabled);
-    }
-
-    private final IAccessibilityManagerClient.Stub mClient =
-            new IAccessibilityManagerClient.Stub() {
-                public void setState(int state) {
-                }
-
-                public void notifyServicesStateChanged() {
-                }
-
-                public void setRelevantEventTypes(int eventTypes) {
-                }
-            };
-
-    /**
-     * Get an AccessibilityManager instance (create one if necessary).
-     *
-     */
-    public static AccessibilityManager getInstance(Context context) {
-        return sInstance;
-    }
-
-    /**
-     * Create an instance.
-     *
-     * @param context A {@link Context}.
-     */
-    public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
-    }
-
-    public IAccessibilityManagerClient getClient() {
-        return mClient;
-    }
-
-    /**
-     * Returns if the {@link AccessibilityManager} is enabled.
-     *
-     * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
-     */
-    public boolean isEnabled() {
-        return false;
-    }
-
-    /**
-     * Returns if the touch exploration in the system is enabled.
-     *
-     * @return True if touch exploration is enabled, false otherwise.
-     */
-    public boolean isTouchExplorationEnabled() {
-        return true;
-    }
-
-    /**
-     * Returns if the high text contrast in the system is enabled.
-     * <p>
-     * <strong>Note:</strong> You need to query this only if you application is
-     * doing its own rendering and does not rely on the platform rendering pipeline.
-     * </p>
-     *
-     */
-    public boolean isHighTextContrastEnabled() {
-        return false;
-    }
-
-    /**
-     * Sends an {@link AccessibilityEvent}.
-     */
-    public void sendAccessibilityEvent(AccessibilityEvent event) {
-    }
-
-    /**
-     * Requests interruption of the accessibility feedback from all accessibility services.
-     */
-    public void interrupt() {
-    }
-
-    /**
-     * Returns the {@link ServiceInfo}s of the installed accessibility services.
-     *
-     * @return An unmodifiable list with {@link ServiceInfo}s.
-     */
-    @Deprecated
-    public List<ServiceInfo> getAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
-     * for a given feedback type.
-     *
-     * @param feedbackTypeFlags The feedback type flags.
-     * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
-     *
-     * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
-     * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
-     * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
-     * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
-     * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
-     */
-    public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
-            int feedbackTypeFlags) {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Registers an {@link AccessibilityStateChangeListener} for changes in
-     * the global accessibility state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers an {@link AccessibilityStateChangeListener} for changes in
-     * the global accessibility state of the system. If the listener has already been registered,
-     * the handler used to call it back is updated.
-     *
-     * @param listener The listener.
-     * @param handler The handler on which the listener should be called back, or {@code null}
-     *                for a callback on the process's main handler.
-     */
-    public void addAccessibilityStateChangeListener(
-            @NonNull AccessibilityStateChangeListener listener, @Nullable Handler handler) {}
-
-    public boolean removeAccessibilityStateChangeListener(
-            AccessibilityStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link TouchExplorationStateChangeListener} for changes in
-     * the global touch exploration state of the system.
-     *
-     * @param listener The listener.
-     * @return True if successfully registered.
-     */
-    public boolean addTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers an {@link TouchExplorationStateChangeListener} for changes in
-     * the global touch exploration state of the system. If the listener has already been
-     * registered, the handler used to call it back is updated.
-     *
-     * @param listener The listener.
-     * @param handler The handler on which the listener should be called back, or {@code null}
-     *                for a callback on the process's main handler.
-     */
-    public void addTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener, @Nullable Handler handler) {}
-
-    /**
-     * Unregisters a {@link TouchExplorationStateChangeListener}.
-     *
-     * @param listener The listener.
-     * @return True if successfully unregistered.
-     */
-    public boolean removeTouchExplorationStateChangeListener(
-            @NonNull TouchExplorationStateChangeListener listener) {
-        return true;
-    }
-
-    /**
-     * Registers a {@link HighTextContrastChangeListener} for changes in
-     * the global high text contrast state of the system.
-     *
-     * @param listener The listener.
-     *
-     * @hide
-     */
-    public void addHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener, @Nullable Handler handler) {}
-
-    /**
-     * Unregisters a {@link HighTextContrastChangeListener}.
-     *
-     * @param listener The listener.
-     *
-     * @hide
-     */
-    public void removeHighTextContrastStateChangeListener(
-            @NonNull HighTextContrastChangeListener listener) {}
-
-    /**
-     * Sets the current state and notifies listeners, if necessary.
-     *
-     * @param stateFlags The state flags.
-     */
-    private void setStateLocked(int stateFlags) {
-    }
-
-    public int addAccessibilityInteractionConnection(IWindow windowToken,
-            IAccessibilityInteractionConnection connection) {
-        return View.NO_ID;
-    }
-
-    public void removeAccessibilityInteractionConnection(IWindow windowToken) {
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
deleted file mode 100644
index dc4f9c8..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Accessor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inputmethod;
-
-/**
- * Class allowing access to package-protected methods/fields.
- */
-public class InputMethodManager_Accessor {
-
-    public static void resetInstance() {
-        InputMethodManager.sInstance = null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java b/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
deleted file mode 100644
index 7c98847..0000000
--- a/tools/layoutlib/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inputmethod;
-
-import com.android.layoutlib.bridge.android.BridgeIInputMethodManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.content.Context;
-import android.os.Looper;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link InputMethodManager}
- *
- * Through the layoutlib_create tool, the original  methods of InputMethodManager have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class InputMethodManager_Delegate {
-
-    // ---- Overridden methods ----
-
-    @LayoutlibDelegate
-    /*package*/ static InputMethodManager getInstance() {
-        synchronized (InputMethodManager.class) {
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm == null) {
-                imm = new InputMethodManager(
-                        new BridgeIInputMethodManager(), Looper.getMainLooper());
-                InputMethodManager.sInstance = imm;
-            }
-            return imm;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java b/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
deleted file mode 100644
index 8e1f218..0000000
--- a/tools/layoutlib/bridge/src/android/view/textservice/TextServicesManager.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.textservice;
-
-import android.os.Bundle;
-import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
-
-import java.util.Locale;
-
-/**
- * A stub class of TextServicesManager for Layout-Lib.
- */
-public final class TextServicesManager {
-    private static final TextServicesManager sInstance = new TextServicesManager();
-    private static final SpellCheckerInfo[] EMPTY_SPELL_CHECKER_INFO = new SpellCheckerInfo[0];
-
-    /**
-     * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
-     * @hide
-     */
-    public static TextServicesManager getInstance() {
-        return sInstance;
-    }
-
-    public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
-            SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo[] getEnabledSpellCheckers() {
-        return EMPTY_SPELL_CHECKER_INFO;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerInfo getCurrentSpellChecker() {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
-            boolean allowImplicitlySelectedSubtype) {
-        return null;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean isSpellCheckerEnabled() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
deleted file mode 100644
index 202f204..0000000
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.os.Bundle;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the WebView.
- * Only non override public methods from the real WebView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class WebView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public WebView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public WebView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.webViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void setHorizontalScrollbarOverlay(boolean overlay) {
-    }
-
-    public void setVerticalScrollbarOverlay(boolean overlay) {
-    }
-
-    public boolean overlayHorizontalScrollbar() {
-        return false;
-    }
-
-    public boolean overlayVerticalScrollbar() {
-        return false;
-    }
-
-    public void savePassword(String host, String username, String password) {
-    }
-
-    public void setHttpAuthUsernamePassword(String host, String realm,
-            String username, String password) {
-    }
-
-    public String[] getHttpAuthUsernamePassword(String host, String realm) {
-        return null;
-    }
-
-    public void destroy() {
-    }
-
-    public static void enablePlatformNotifications() {
-    }
-
-    public static void disablePlatformNotifications() {
-    }
-
-    public void loadUrl(String url) {
-    }
-
-    public void loadData(String data, String mimeType, String encoding) {
-    }
-
-    public void loadDataWithBaseURL(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl) {
-    }
-
-    public void stopLoading() {
-    }
-
-    public void reload() {
-    }
-
-    public boolean canGoBack() {
-        return false;
-    }
-
-    public void goBack() {
-    }
-
-    public boolean canGoForward() {
-        return false;
-    }
-
-    public void goForward() {
-    }
-
-    public boolean canGoBackOrForward(int steps) {
-        return false;
-    }
-
-    public void goBackOrForward(int steps) {
-    }
-
-    public boolean pageUp(boolean top) {
-        return false;
-    }
-    
-    public boolean pageDown(boolean bottom) {
-        return false;
-    }
-
-    public void clearView() {
-    }
-    
-    public Picture capturePicture() {
-        return null;
-    }
-
-    public float getScale() {
-        return 0;
-    }
-
-    public void setInitialScale(int scaleInPercent) {
-    }
-
-    public void invokeZoomPicker() {
-    }
-
-    public void requestFocusNodeHref(Message hrefMsg) {
-    }
-
-    public void requestImageRef(Message msg) {
-    }
-
-    public String getUrl() {
-        return null;
-    }
-
-    public String getTitle() {
-        return null;
-    }
-
-    public Bitmap getFavicon() {
-        return null;
-    }
-
-    public int getProgress() {
-        return 0;
-    }
-    
-    public int getContentHeight() {
-        return 0;
-    }
-
-    public void pauseTimers() {
-    }
-
-    public void resumeTimers() {
-    }
-
-    public void clearCache() {
-    }
-
-    public void clearFormData() {
-    }
-
-    public void clearHistory() {
-    }
-
-    public void clearSslPreferences() {
-    }
-
-    public static String findAddress(String addr) {
-        return null;
-    }
-
-    public void documentHasImages(Message response) {
-    }
-
-    public void setWebViewClient(WebViewClient client) {
-    }
-
-    public void setDownloadListener(DownloadListener listener) {
-    }
-
-    public void setWebChromeClient(WebChromeClient client) {
-    }
-
-    public void addJavascriptInterface(Object obj, String interfaceName) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-
-    public boolean zoomIn() {
-        return false;
-    }
-
-    public boolean zoomOut() {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java b/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
deleted file mode 100644
index fdd1779..0000000
--- a/tools/layoutlib/bridge/src/android/widget/Toolbar_Accessor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.widget;
-
-import android.content.Context;
-
-/**
- * To access non public members of classes in {@link Toolbar}
- */
-public class Toolbar_Accessor {
-    public static ActionMenuPresenter getActionMenuPresenter(Toolbar toolbar) {
-        return toolbar.getOuterActionMenuPresenter();
-    }
-
-    public static Context getPopupContext(Toolbar toolbar) {
-        return toolbar.getPopupContext();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
deleted file mode 100644
index 01fe45d..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/VirtualRefBasePtr_Delegate.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.util.LongSparseLongArray;
-
-/**
- * Delegate used to provide new implementation the native methods of {@link VirtualRefBasePtr}
- *
- * Through the layoutlib_create tool, the original native  methods of VirtualRefBasePtr have been
- * replaced by calls to methods of the same name in this delegate class.
- *
- */
-@SuppressWarnings("unused")
-public class VirtualRefBasePtr_Delegate {
-    private static final DelegateManager<Object> sManager = new DelegateManager<>(Object.class);
-    private static final LongSparseLongArray sRefCount = new LongSparseLongArray();
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nIncStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-        sRefCount.put(ptr, ++counter);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static synchronized void nDecStrong(long ptr) {
-        long counter = sRefCount.get(ptr);
-
-        if (counter > 1) {
-            sRefCount.put(ptr, --counter);
-        } else {
-            sRefCount.delete(ptr);
-            sManager.removeJavaReferenceFor(ptr);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
deleted file mode 100644
index bf998b8..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
- *
- * Through the layoutlib_create tool, the original  methods of XmlUtils have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class XmlUtils_Delegate {
-
-    @LayoutlibDelegate
-    /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
-        if (null == charSeq)
-            return defaultValue;
-
-        String nm = charSeq.toString();
-
-        // This code is copied from the original implementation. The issue is that
-        // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
-        // is > 80000000 but the Java VM cannot.
-
-        int sign = 1;
-        int index = 0;
-        int len = nm.length();
-        int base = 10;
-
-        if ('-' == nm.charAt(0)) {
-            sign = -1;
-            index++;
-        }
-
-        if ('0' == nm.charAt(index)) {
-            //  Quick check for a zero by itself
-            if (index == (len - 1))
-                return 0;
-
-            char c = nm.charAt(index + 1);
-
-            if ('x' == c || 'X' == c) {
-                index += 2;
-                base = 16;
-            } else {
-                index++;
-                base = 8;
-            }
-        }
-        else if ('#' == nm.charAt(index)) {
-            index++;
-            base = 16;
-        }
-
-        return ((int)Long.parseLong(nm.substring(index), base)) * sign;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
deleted file mode 100644
index da1ab27..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.view.animation;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.graphics.Path;
-import android.util.MathUtils;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnticipateInterpolator;
-import android.view.animation.AnticipateOvershootInterpolator;
-import android.view.animation.BaseInterpolator;
-import android.view.animation.BounceInterpolator;
-import android.view.animation.CycleInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.OvershootInterpolator;
-import android.view.animation.PathInterpolator;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link
- * NativeInterpolatorFactoryHelper}
- * <p>
- * Through the layoutlib_create tool, the original  methods of NativeInterpolatorFactoryHelper have
- * been replaced by calls to methods of the same name in this delegate class.
- */
-@SuppressWarnings("unused")
-public class NativeInterpolatorFactoryHelper_Delegate {
-    private static final DelegateManager<Interpolator> sManager = new DelegateManager<>
-            (Interpolator.class);
-
-    public static Interpolator getDelegate(long nativePtr) {
-        return sManager.getDelegate(nativePtr);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateDecelerateInterpolator() {
-        return sManager.addNewDelegate(new AccelerateDecelerateInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAccelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new AccelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createAnticipateOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new AnticipateOvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createBounceInterpolator() {
-        return sManager.addNewDelegate(new BounceInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createCycleInterpolator(float cycles) {
-        return sManager.addNewDelegate(new CycleInterpolator(cycles));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createDecelerateInterpolator(float factor) {
-        return sManager.addNewDelegate(new DecelerateInterpolator(factor));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLinearInterpolator() {
-        return sManager.addNewDelegate(new LinearInterpolator());
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createOvershootInterpolator(float tension) {
-        return sManager.addNewDelegate(new OvershootInterpolator(tension));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createPathInterpolator(float[] x, float[] y) {
-        Path path = new Path();
-        path.moveTo(x[0], y[0]);
-        for (int i = 1; i < x.length; i++) {
-            path.lineTo(x[i], y[i]);
-        }
-        return sManager.addNewDelegate(new PathInterpolator(path));
-    }
-
-    private static class LutInterpolator extends BaseInterpolator {
-        private final float[] mValues;
-        private final int mSize;
-
-        private LutInterpolator(float[] values) {
-            mValues = values;
-            mSize = mValues.length;
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            float lutpos = input * (mSize - 1);
-            if (lutpos >= (mSize - 1)) {
-                return mValues[mSize - 1];
-            }
-
-            int ipart = (int) lutpos;
-            float weight = lutpos - ipart;
-
-            int i1 = ipart;
-            int i2 = Math.min(i1 + 1, mSize - 1);
-
-            assert i1 >= 0 && i2 >= 0 : "Negatives in the interpolation";
-
-            return MathUtils.lerp(mValues[i1], mValues[i2], weight);
-        }
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static long createLutInterpolator(float[] values) {
-        return sManager.addNewDelegate(new LutInterpolator(values));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
deleted file mode 100644
index bb95c4e..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/BridgeMenuItemImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.view.menu;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.content.Context;
-import android.view.View;
-
-/**
- * An extension of the {@link MenuItemImpl} to store the view cookie also.
- */
-public class BridgeMenuItemImpl extends MenuItemImpl {
-
-    /**
-     * An object returned by the IDE that helps mapping each View to the corresponding XML tag in
-     * the layout. For Menus, we store this cookie here and attach it to the corresponding view
-     * at the time of rendering.
-     */
-    private Object viewCookie;
-    private BridgeContext mContext;
-
-    /**
-     * Instantiates this menu item.
-     */
-    BridgeMenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
-            CharSequence title, int showAsAction) {
-        super(menu, group, id, categoryOrder, ordering, title, showAsAction);
-        Context context = menu.getContext();
-        context = BridgeContext.getBaseContext(context);
-        if (context instanceof BridgeContext) {
-            mContext = ((BridgeContext) context);
-        }
-    }
-
-    public Object getViewCookie() {
-        return viewCookie;
-    }
-
-    public void setViewCookie(Object viewCookie) {
-        // If the menu item has an associated action provider view,
-        // directly set the cookie in the view to cookie map stored in BridgeContext.
-        View actionView = getActionView();
-        if (actionView != null && mContext != null) {
-            mContext.addViewKey(actionView, viewCookie);
-            // We don't need to add the view cookie to the this item now. But there's no harm in
-            // storing it, in case we need it in the future.
-        }
-        this.viewCookie = viewCookie;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
deleted file mode 100644
index 505fb81..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/view/menu/MenuBuilder_Delegate.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.view.menu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide new implementation of a select few methods of {@link MenuBuilder}
- * <p/>
- * Through the layoutlib_create tool, the original  methods of {@code MenuBuilder} have been
- * replaced by calls to methods of the same name in this delegate class.
- */
-public class MenuBuilder_Delegate {
-    /**
-     * The method overrides the instantiation of the {@link MenuItemImpl} with an instance of
-     * {@link BridgeMenuItemImpl} so that view cookies may be stored.
-     */
-    @LayoutlibDelegate
-    /*package*/ static MenuItemImpl createNewMenuItem(MenuBuilder thisMenu, int group, int id,
-            int categoryOrder, int ordering, CharSequence title, int defaultShowAsAction) {
-        return new BridgeMenuItemImpl(thisMenu, group, id, categoryOrder, ordering, title,
-                defaultShowAsAction);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java b/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
deleted file mode 100644
index 40b6220..0000000
--- a/tools/layoutlib/bridge/src/com/android/internal/widget/ActionBarAccessor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.widget;
-
-import android.widget.ActionMenuPresenter;
-
-/**
- * To access non public members of AbsActionBarView
- */
-public class ActionBarAccessor {
-
-    /**
-     * Returns the {@link ActionMenuPresenter} associated with the {@link AbsActionBarView}
-     */
-    public static ActionMenuPresenter getActionMenuPresenter(AbsActionBarView view) {
-        return view.mActionMenuPresenter;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 93fd005..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Capability;
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.Features;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderDrawable;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.layoutlib.bridge.util.DynamicIdMap;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.create.MethodAdapter;
-import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.content.res.BridgeAssetManager;
-import android.graphics.Bitmap;
-import android.graphics.FontFamily_Delegate;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Delegate;
-import android.icu.util.ULocale;
-import android.os.Looper;
-import android.os.Looper_Accessor;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import java.io.File;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-import libcore.io.MemoryMappedFile_Delegate;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-
-/**
- * Main entry point of the LayoutLib Bridge.
- * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #createSession(SessionParams)}
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-
-    private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
-
-    public static class StaticMethodNotImplementedException extends RuntimeException {
-        private static final long serialVersionUID = 1L;
-
-        public StaticMethodNotImplementedException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Lock to ensure only one rendering/inflating happens at a time.
-     * This is due to some singleton in the Android framework.
-     */
-    private final static ReentrantLock sLock = new ReentrantLock();
-
-    /**
-     * Maps from id to resource type/name. This is for com.android.internal.R
-     */
-    @SuppressWarnings("deprecation")
-    private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<>();
-
-    /**
-     * Reverse map compared to sRMap, resource type -> (resource name -> id).
-     * This is for com.android.internal.R.
-     */
-    private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<>(ResourceType.class);
-
-    // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
-    // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
-    // collision which should be fine.
-    private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
-    private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
-
-    private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
-            new HashMap<>();
-    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
-
-            new HashMap<>();
-
-    private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache = new HashMap<>();
-    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
-            new HashMap<>();
-
-    private static Map<String, Map<String, Integer>> sEnumValueMap;
-    private static Map<String, String> sPlatformProperties;
-
-    /**
-     * A default log than prints to stdout/stderr.
-     */
-    private final static LayoutLog sDefaultLog = new LayoutLog() {
-        @Override
-        public void error(String tag, String message, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void error(String tag, String message, Throwable throwable, Object data) {
-            System.err.println(message);
-        }
-
-        @Override
-        public void warning(String tag, String message, Object data) {
-            System.out.println(message);
-        }
-    };
-
-    /**
-     * Current log.
-     */
-    private static LayoutLog sCurrentLog = sDefaultLog;
-
-    private static final int LAST_SUPPORTED_FEATURE = Features.THEME_PREVIEW_NAVIGATION_BAR;
-
-    @Override
-    public int getApiLevel() {
-        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    @Deprecated
-    public EnumSet<Capability> getCapabilities() {
-        // The Capability class is deprecated and frozen. All Capabilities enumerated there are
-        // supported by this version of LayoutLibrary. So, it's safe to use EnumSet.allOf()
-        return EnumSet.allOf(Capability.class);
-    }
-
-    @Override
-    public boolean supports(int feature) {
-        return feature <= LAST_SUPPORTED_FEATURE;
-    }
-
-    @Override
-    public boolean init(Map<String,String> platformProperties,
-            File fontLocation,
-            Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
-        sPlatformProperties = platformProperties;
-        sEnumValueMap = enumValueMap;
-
-        BridgeAssetManager.initSystem();
-
-        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
-        // on static (native) methods which prints the signature on the console and
-        // throws an exception.
-        // This is useful when testing the rendering in ADT to identify static native
-        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
-        // which is generally OK yet might be a problem, so this is how you'd find out.
-        //
-        // Currently layoutlib_create only overrides static native method.
-        // Static non-natives are not overridden and thus do not get here.
-        final String debug = System.getenv("DEBUG_LAYOUT");
-        if (debug != null && !debug.equals("0") && !debug.equals("false")) {
-
-            OverrideMethod.setDefaultListener(new MethodAdapter() {
-                @Override
-                public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    sDefaultLog.error(null, "Missing Stub: " + signature +
-                            (isNative ? " (native)" : ""), null /*data*/);
-
-                    if (debug.equalsIgnoreCase("throw")) {
-                        // Throwing this exception doesn't seem that useful. It breaks
-                        // the layout editor yet doesn't display anything meaningful to the
-                        // user. Having the error in the console is just as useful. We'll
-                        // throw it only if the environment variable is "throw" or "THROW".
-                        throw new StaticMethodNotImplementedException(signature);
-                    }
-                }
-            });
-        }
-
-        // load the fonts.
-        FontFamily_Delegate.setFontLocation(fontLocation.getAbsolutePath());
-        MemoryMappedFile_Delegate.setDataDir(fontLocation.getAbsoluteFile().getParentFile());
-
-        // now parse com.android.internal.R (and only this one as android.R is a subset of
-        // the internal version), and put the content in the maps.
-        try {
-            Class<?> r = com.android.internal.R.class;
-            // Parse the styleable class first, since it may contribute to attr values.
-            parseStyleable();
-
-            for (Class<?> inner : r.getDeclaredClasses()) {
-                if (inner == com.android.internal.R.styleable.class) {
-                    // Already handled the styleable case. Not skipping attr, as there may be attrs
-                    // that are not referenced from styleables.
-                    continue;
-                }
-                String resTypeName = inner.getSimpleName();
-                ResourceType resType = ResourceType.getEnum(resTypeName);
-                if (resType != null) {
-                    Map<String, Integer> fullMap = null;
-                    switch (resType) {
-                        case ATTR:
-                            fullMap = sRevRMap.get(ResourceType.ATTR);
-                            break;
-                        case STRING:
-                        case STYLE:
-                            // Slightly less than thousand entries in each.
-                            fullMap = new HashMap<>(1280);
-                            // no break.
-                        default:
-                            if (fullMap == null) {
-                                fullMap = new HashMap<>();
-                            }
-                            sRevRMap.put(resType, fullMap);
-                    }
-
-                    for (Field f : inner.getDeclaredFields()) {
-                        // only process static final fields. Since the final attribute may have
-                        // been altered by layoutlib_create, we only check static
-                        if (!isValidRField(f)) {
-                            continue;
-                        }
-                        Class<?> type = f.getType();
-                        if (!type.isArray()) {
-                            Integer value = (Integer) f.get(null);
-                            //noinspection deprecation
-                            sRMap.put(value, Pair.of(resType, f.getName()));
-                            fullMap.put(f.getName(), value);
-                        }
-                    }
-                }
-            }
-        } catch (Exception throwable) {
-            if (log != null) {
-                log.error(LayoutLog.TAG_BROKEN,
-                        "Failed to load com.android.internal.R from the layout library jar",
-                        throwable, null);
-            }
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Tests if the field is pubic, static and one of int or int[].
-     */
-    private static boolean isValidRField(Field field) {
-        int modifiers = field.getModifiers();
-        boolean isAcceptable = Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
-        Class<?> type = field.getType();
-        return isAcceptable && type == int.class ||
-                (type.isArray() && type.getComponentType() == int.class);
-
-    }
-
-    private static void parseStyleable() throws Exception {
-        // R.attr doesn't contain all the needed values. There are too many resources in the
-        // framework for all to be in the R class. Only the ones specified manually in
-        // res/values/symbols.xml are put in R class. Since, we need to create a map of all attr
-        // values, we try and find them from the styleables.
-
-        // There were 1500 elements in this map at M timeframe.
-        Map<String, Integer> revRAttrMap = new HashMap<>(2048);
-        sRevRMap.put(ResourceType.ATTR, revRAttrMap);
-        // There were 2000 elements in this map at M timeframe.
-        Map<String, Integer> revRStyleableMap = new HashMap<>(3072);
-        sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap);
-        Class<?> c = com.android.internal.R.styleable.class;
-        Field[] fields = c.getDeclaredFields();
-        // Sort the fields to bring all arrays to the beginning, so that indices into the array are
-        // able to refer back to the arrays (i.e. no forward references).
-        Arrays.sort(fields, (o1, o2) -> {
-            if (o1 == o2) {
-                return 0;
-            }
-            Class<?> t1 = o1.getType();
-            Class<?> t2 = o2.getType();
-            if (t1.isArray() && !t2.isArray()) {
-                return -1;
-            } else if (t2.isArray() && !t1.isArray()) {
-                return 1;
-            }
-            return o1.getName().compareTo(o2.getName());
-        });
-        Map<String, int[]> styleables = new HashMap<>();
-        for (Field field : fields) {
-            if (!isValidRField(field)) {
-                // Only consider public static fields that are int or int[].
-                // Don't check the final flag as it may have been modified by layoutlib_create.
-                continue;
-            }
-            String name = field.getName();
-            if (field.getType().isArray()) {
-                int[] styleableValue = (int[]) field.get(null);
-                styleables.put(name, styleableValue);
-                continue;
-            }
-            // Not an array.
-            String arrayName = name;
-            int[] arrayValue = null;
-            int index;
-            while ((index = arrayName.lastIndexOf('_')) >= 0) {
-                // Find the name of the corresponding styleable.
-                // Search in reverse order so that attrs like LinearLayout_Layout_layout_gravity
-                // are mapped to LinearLayout_Layout and not to LinearLayout.
-                arrayName = arrayName.substring(0, index);
-                arrayValue = styleables.get(arrayName);
-                if (arrayValue != null) {
-                    break;
-                }
-            }
-            index = (Integer) field.get(null);
-            if (arrayValue != null) {
-                String attrName = name.substring(arrayName.length() + 1);
-                int attrValue = arrayValue[index];
-                //noinspection deprecation
-                sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName));
-                revRAttrMap.put(attrName, attrValue);
-            }
-            //noinspection deprecation
-            sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name));
-            revRStyleableMap.put(name, index);
-        }
-    }
-
-    @Override
-    public boolean dispose() {
-        BridgeAssetManager.clearSystem();
-
-        // dispose of the default typeface.
-        Typeface_Delegate.resetDefaults();
-        Typeface.sDynamicTypefaceCache.evictAll();
-
-        return true;
-    }
-
-    /**
-     * Starts a layout session by inflating and rendering it. The method returns a
-     * {@link RenderSession} on which further actions can be taken.
-     * <p/>
-     * If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE},
-     * this method will only inflate the layout but will NOT render it.
-     * @param params the {@link SessionParams} object with all the information necessary to create
-     *           the scene.
-     * @return a new {@link RenderSession} object that contains the result of the layout.
-     * @since 5
-     */
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        try {
-            Result lastResult;
-            RenderSessionImpl scene = new RenderSessionImpl(params);
-            try {
-                prepareThread();
-                lastResult = scene.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = scene.inflate();
-
-                    boolean doNotRenderOnCreate = Boolean.TRUE.equals(
-                            params.getFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE));
-                    if (lastResult.isSuccess() && !doNotRenderOnCreate) {
-                        lastResult = scene.render(true /*freshRender*/);
-                    }
-                }
-            } finally {
-                scene.release();
-                cleanupThread();
-            }
-
-            return new BridgeRenderSession(scene, lastResult);
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return new BridgeRenderSession(null,
-                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
-        }
-    }
-
-    @Override
-    public Result renderDrawable(DrawableParams params) {
-        try {
-            Result lastResult;
-            RenderDrawable action = new RenderDrawable(params);
-            try {
-                prepareThread();
-                lastResult = action.init(params.getTimeout());
-                if (lastResult.isSuccess()) {
-                    lastResult = action.render();
-                }
-            } finally {
-                action.release();
-                cleanupThread();
-            }
-
-            return lastResult;
-        } catch (Throwable t) {
-            // get the real cause of the exception.
-            Throwable t2 = t;
-            while (t2.getCause() != null) {
-                t2 = t.getCause();
-            }
-            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
-        }
-    }
-
-    @Override
-    public void clearCaches(Object projectKey) {
-        if (projectKey != null) {
-            sProjectBitmapCache.remove(projectKey);
-            sProject9PatchCache.remove(projectKey);
-        }
-    }
-
-    @Override
-    public Result getViewParent(Object viewObject) {
-        if (viewObject instanceof View) {
-            return Status.SUCCESS.createResult(((View)viewObject).getParent());
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public Result getViewIndex(Object viewObject) {
-        if (viewObject instanceof View) {
-            View view = (View) viewObject;
-            ViewParent parentView = view.getParent();
-
-            if (parentView instanceof ViewGroup) {
-                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
-            }
-
-            return Status.SUCCESS.createResult();
-        }
-
-        throw new IllegalArgumentException("viewObject is not a View");
-    }
-
-    @Override
-    public boolean isRtl(String locale) {
-        return isLocaleRtl(locale);
-    }
-
-    public static boolean isLocaleRtl(String locale) {
-        if (locale == null) {
-            locale = "";
-        }
-        ULocale uLocale = new ULocale(locale);
-        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL);
-    }
-
-    /**
-     * Returns the lock for the bridge
-     */
-    public static ReentrantLock getLock() {
-        return sLock;
-    }
-
-    /**
-     * Prepares the current thread for rendering.
-     *
-     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
-     * will do the clean-up, and make the thread unable to do further scene actions.
-     */
-    public synchronized static void prepareThread() {
-        // we need to make sure the Looper has been initialized for this thread.
-        // this is required for View that creates Handler objects.
-        if (Looper.myLooper() == null) {
-            Looper.prepareMainLooper();
-        }
-    }
-
-    /**
-     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
-     * <p>
-     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
-     * call to this will prevent the thread from doing further scene actions
-     */
-    public synchronized static void cleanupThread() {
-        // clean up the looper
-        Looper_Accessor.cleanupThread();
-    }
-
-    public static LayoutLog getLog() {
-        return sCurrentLog;
-    }
-
-    public static void setLog(LayoutLog log) {
-        // check only the thread currently owning the lock can do this.
-        if (!sLock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-
-        if (log != null) {
-            sCurrentLog = log;
-        } else {
-            sCurrentLog = sDefaultLog;
-        }
-    }
-
-    /**
-     * Returns details of a framework resource from its integer value.
-     * @param value the integer value
-     * @return a Pair containing the resource type and name, or null if the id
-     *     does not match any resource.
-     */
-    @SuppressWarnings("deprecation")
-    public static Pair<ResourceType, String> resolveResourceId(int value) {
-        Pair<ResourceType, String> pair = sRMap.get(value);
-        if (pair == null) {
-            pair = sDynamicIds.resolveId(value);
-        }
-        return pair;
-    }
-
-    /**
-     * Returns the integer id of a framework resource, from a given resource type and resource name.
-     * <p/>
-     * If no resource is found, it creates a dynamic id for the resource.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource.
-     *
-     * @return an {@link Integer} containing the resource id.
-     */
-    @NonNull
-    public static Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> map = sRevRMap.get(type);
-        Integer value = null;
-        if (map != null) {
-            value = map.get(name);
-        }
-
-        return value == null ? sDynamicIds.getId(type, name) : value;
-
-    }
-
-    /**
-     * Returns the list of possible enums for a given attribute name.
-     */
-    public static Map<String, Integer> getEnumValues(String attributeName) {
-        if (sEnumValueMap != null) {
-            return sEnumValueMap.get(attributeName);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the platform build properties.
-     */
-    public static Map<String, String> getPlatformProperties() {
-        return sPlatformProperties;
-    }
-
-    /**
-     * Returns the bitmap for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the bitmap
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached Bitmap or null if not found.
-     */
-    public static Bitmap getCachedBitmap(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
-            if (map != null) {
-                SoftReference<Bitmap> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a bitmap in a project cache or in the framework cache.
-     * @param value the path of the bitmap
-     * @param bmp the Bitmap object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<Bitmap>> map =
-                    sProjectBitmapCache.computeIfAbsent(projectKey, k -> new HashMap<>());
-
-            map.put(value, new SoftReference<>(bmp));
-        } else {
-            sFrameworkBitmapCache.put(value, new SoftReference<>(bmp));
-        }
-    }
-
-    /**
-     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
-     * framework cache.
-     * @param value the path of the 9 patch
-     * @param projectKey the key of the project, or null to query the framework cache.
-     * @return the cached 9 patch or null if not found.
-     */
-    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
-
-            if (map != null) {
-                SoftReference<NinePatchChunk> ref = map.get(value);
-                if (ref != null) {
-                    return ref.get();
-                }
-            }
-        } else {
-            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
-            if (ref != null) {
-                return ref.get();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Sets a 9 patch chunk in a project cache or in the framework cache.
-     * @param value the path of the 9 patch
-     * @param ninePatch the 9 patch object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
-     */
-    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatchChunk>> map =
-                    sProject9PatchCache.computeIfAbsent(projectKey, k -> new HashMap<>());
-
-            map.put(value, new SoftReference<>(ninePatch));
-        } else {
-            sFramework9PatchCache.put(value, new SoftReference<>(ninePatch));
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
deleted file mode 100644
index 6228766..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-/**
- * Constant definition class.<br>
- * <br>
- * Most constants have a prefix defining the content.
- * <ul>
- * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
- * from the project root.</li>
- * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
- * <li><code>FN_</code> File name constant.</li>
- * <li><code>FD_</code> Folder name constant.</li>
- * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
- * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
- * <li><code>RE_</code> Regexp constant.</li>
- * <li><code>NS_</code> Namespace constant.</li>
- * <li><code>CLASS_</code> Fully qualified class name.</li>
- * </ul>
- *
- */
-public class BridgeConstants {
-
-    /** Namespace for the resource XML */
-    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
-
-    /** App auto namespace */
-    public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
-    public final static String NS_TOOLS_URI = "http://schemas.android.com/tools";
-
-    public final static String R = "com.android.internal.R";
-
-
-    public final static String MATCH_PARENT = "match_parent";
-    public final static String FILL_PARENT = "fill_parent";
-    public final static String WRAP_CONTENT = "wrap_content";
-
-    // Should be kept in sync with LayoutMetadata.KEY_LV_ITEM in tools/adt/idea
-    /** Attribute in the tools namespace used to specify layout manager for RecyclerView. */
-    @SuppressWarnings("SpellCheckingInspection")
-    public static final String ATTR_LIST_ITEM = "listitem";
-    public static final String ATTR_OPEN_DRAWER = "openDrawer";
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
deleted file mode 100644
index fdf6d63..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.PropertiesMap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.awt.image.BufferedImage;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An implementation of {@link RenderSession}.
- *
- * This is a pretty basic class that does almost nothing. All of the work is done in
- * {@link RenderSessionImpl}.
- *
- */
-public class BridgeRenderSession extends RenderSession {
-
-    @Nullable
-    private final RenderSessionImpl mSession;
-    @NonNull
-    private Result mLastResult;
-
-    @Override
-    public Result getResult() {
-        return mLastResult;
-    }
-
-    @Override
-    public BufferedImage getImage() {
-        return mSession != null ? mSession.getImage() :
-                new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
-    }
-
-    @Override
-    public boolean isAlphaChannelImage() {
-        return mSession != null && mSession.isAlphaChannelImage();
-    }
-
-    @Override
-    public List<ViewInfo> getRootViews() {
-        return mSession != null ? mSession.getViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public List<ViewInfo> getSystemRootViews() {
-        return mSession != null ? mSession.getSystemViewInfos() : Collections.emptyList();
-    }
-
-    @Override
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mSession != null ? mSession.getDefaultProperties() : Collections.emptyMap();
-    }
-
-    @Override
-    public Result measure(long timeout) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    mSession.invalidateRenderingSize();
-                    mLastResult = mSession.measure();
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result render(long timeout, boolean forceMeasure) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(timeout);
-                if (mLastResult.isSuccess()) {
-                    if (forceMeasure) {
-                        mSession.invalidateRenderingSize();
-                    }
-                    mLastResult = mSession.render(false /*freshRender*/);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
-                            listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
-            IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult =
-                            mSession.insertChild((ViewGroup) parentView, childXml, index, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-
-    @Override
-    public Result moveChild(Object parentView, Object childView, int index,
-            Map<String, String> layoutParams, IAnimationListener listener) {
-        if (!(parentView instanceof ViewGroup)) {
-            throw new IllegalArgumentException("parentView is not a ViewGroup");
-        }
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
-                            layoutParams, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public Result removeChild(Object childView, IAnimationListener listener) {
-        if (!(childView instanceof View)) {
-            throw new IllegalArgumentException("childView is not a View");
-        }
-
-        if (mSession != null) {
-            try {
-                Bridge.prepareThread();
-                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
-                if (mLastResult.isSuccess()) {
-                    mLastResult = mSession.removeChild((View) childView, listener);
-                }
-            } finally {
-                mSession.release();
-                Bridge.cleanupThread();
-            }
-        }
-
-        return mLastResult;
-    }
-
-    @Override
-    public void setSystemTimeNanos(long nanos) {
-        System_Delegate.setNanosTime(nanos);
-    }
-
-    @Override
-    public void setSystemBootTimeNanos(long nanos) {
-        System_Delegate.setBootTimeNanos(nanos);
-    }
-
-    @Override
-    public void setElapsedFrameTimeNanos(long nanos) {
-        if (mSession != null) {
-            mSession.setElapsedFrameTimeNanos(nanos);
-        }
-    }
-
-    @Override
-    public void dispose() {
-        if (mSession != null) {
-            mSession.dispose();
-        }
-    }
-
-    /*package*/ BridgeRenderSession(@Nullable RenderSessionImpl scene, @NonNull Result lastResult) {
-        mSession = scene;
-        if (scene != null) {
-            mSession.setScene(this);
-        }
-        mLastResult = lastResult;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
deleted file mode 100644
index e10f20d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-/**
- * Base class for mocked views.
- * <p/>
- * FrameLayout with a single TextView. Doesn't allow adding any other views to itself.
- */
-public class MockView extends FrameLayout {
-
-    private final TextView mView;
-
-    public MockView(Context context) {
-        this(context, null);
-    }
-
-    public MockView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public MockView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        mView = new TextView(context, attrs);
-        mView.setTextColor(0xFF000000);
-        setGravity(Gravity.CENTER);
-        setText(getClass().getSimpleName());
-        addView(mView);
-        setBackgroundColor(0xFF7F7F7F);
-    }
-
-    // Only allow adding one TextView.
-    @Override
-    public void addView(View child) {
-        if (child == mView) {
-            super.addView(child);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index) {
-        if (child == mView) {
-            super.addView(child, index);
-        }
-    }
-
-    @Override
-    public void addView(View child, int width, int height) {
-        if (child == mView) {
-            super.addView(child, width, height);
-        }
-    }
-
-    @Override
-    public void addView(View child, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, params);
-        }
-    }
-
-    @Override
-    public void addView(View child, int index, ViewGroup.LayoutParams params) {
-        if (child == mView) {
-            super.addView(child, index, params);
-        }
-    }
-
-    // The following methods are called by the IDE via reflection, and should be considered part
-    // of the API.
-    // Historically, MockView used to be a textView and had these methods. Now, we simply delegate
-    // them to the contained textView.
-
-    public void setText(CharSequence text) {
-        mView.setText(text);
-    }
-
-    @SuppressWarnings("WeakerAccess") // This method is used from Studio
-    public void setGravity(int gravity) {
-        mView.setGravity(gravity);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
deleted file mode 100644
index faaf105..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.RenderAction;
-
-import android.icu.util.ULocale;
-
-import java.util.Locale;
-
-/**
- * This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag}
- * which is only available after Java 6.
- *
- * The create tool re-writes references to the above mentioned method to this one. Hence it's
- * imperative that this class is not deleted unless the create tool is modified.
- */
-@SuppressWarnings("UnusedDeclaration")
-public class AndroidLocale {
-
-    public static String toLanguageTag(Locale locale)  {
-        return ULocale.forLocale(locale).toLanguageTag();
-    }
-
-    public static String adjustLanguageCode(String languageCode) {
-        String adjusted = languageCode.toLowerCase(Locale.US);
-        // Map new language codes to the obsolete language
-        // codes so the correct resource bundles will be used.
-        if (languageCode.equals("he")) {
-            adjusted = "iw";
-        } else if (languageCode.equals("id")) {
-            adjusted = "in";
-        } else if (languageCode.equals("yi")) {
-            adjusted = "ji";
-        }
-
-        return adjusted;
-    }
-
-    public static Locale forLanguageTag(String tag) {
-        return ULocale.forLanguageTag(tag).toLocale();
-    }
-
-    public static String getScript(Locale locale) {
-        return ULocale.forLocale(locale).getScript();
-    }
-
-    public static Locale getDefault() {
-        BridgeContext context = RenderAction.getCurrentContext();
-        if (context != null) {
-            Locale locale = context.getConfiguration().locale;
-            if (locale != null) {
-                return locale;
-            }
-        }
-        return Locale.getDefault();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
deleted file mode 100644
index c827f17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentValues;
-import android.content.IContentProvider;
-import android.content.OperationApplicationException;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ICancellationSignal;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-
-/**
- * Mock implementation of {@link IContentProvider}.
- *
- * TODO: never return null when the method is not supposed to. Return fake data instead.
- */
-public final class BridgeContentProvider implements IContentProvider {
-    @Override
-    public ContentProviderResult[] applyBatch(String callingPackage,
-            ArrayList<ContentProviderOperation> arg0)
-            throws RemoteException, OperationApplicationException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int bulkInsert(String callingPackage, Uri arg0, ContentValues[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public Bundle call(String callingPackage, String arg0, String arg1, Bundle arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int delete(String callingPackage, Uri arg0, String arg1, String[] arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public String getType(Uri arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Uri insert(String callingPackage, Uri arg0, ContentValues arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openAssetFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token)
-            throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Cursor query(String callingPackage, Uri arg0, String[] arg1,
-            Bundle arg3, ICancellationSignal arg4) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int update(String callingPackage, Uri arg0, ContentValues arg1, String arg2,
-            String[] arg3) throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
-            Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ICancellationSignal createCancellationSignal() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-
-    @Override
-    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
-        return null;
-    }
-
-    @Override
-    public boolean refresh(String callingPkg, Uri url, Bundle args,
-                    ICancellationSignal cancellationSignal) throws RemoteException {
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
deleted file mode 100644
index 8d259d7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * A mock content resolver for the LayoutLib Bridge.
- * <p/>
- * It won't serve any actual data but it's good enough for all
- * the widgets which expect to have a content resolver available via
- * {@link BridgeContext#getContentResolver()}.
- */
-public class BridgeContentResolver extends ContentResolver {
-
-    private BridgeContentProvider mProvider = null;
-
-    public BridgeContentResolver(Context context) {
-        super(context);
-    }
-
-    @Override
-    public IContentProvider acquireProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public IContentProvider acquireExistingProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public boolean releaseProvider(IContentProvider icp) {
-        // ignore
-        return false;
-    }
-
-    @Override
-    protected IContentProvider acquireUnstableProvider(Context c, String name) {
-        return acquireProvider(c, name);
-    }
-
-    @Override
-    public boolean releaseUnstableProvider(IContentProvider icp) {
-        return releaseProvider(icp);
-    }
-
-    /** @hide */
-    @Override
-    public void unstableProviderDied(IContentProvider icp) {
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void startSync(Uri uri, Bundle extras) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void cancelSync(Uri uri) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
deleted file mode 100644
index 8bd924e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ /dev/null
@@ -1,2059 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.Stack;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-import com.android.util.PropertiesMap.Property;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.SystemServiceRegistry_Accessor;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.BridgeAssetManager;
-import android.content.res.BridgeTypedArray;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.Resources.Theme;
-import android.content.res.Resources_Delegate;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.Display;
-import android.view.DisplayAdjustments;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-import android.view.textservice.TextServicesManager;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
-
-/**
- * Custom implementation of Context/Activity to handle non compiled resources.
- */
-@SuppressWarnings("deprecation")  // For use of Pair.
-public class BridgeContext extends Context {
-    private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
-
-    private static final Map<String, ResourceValue> FRAMEWORK_PATCHED_VALUES = new HashMap<>(2);
-    private static final Map<String, ResourceValue> FRAMEWORK_REPLACE_VALUES = new HashMap<>(3);
-
-    static {
-        FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue(
-                ResourceType.BOOL, "animateFirstView", "false", false));
-        FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
-                new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false));
-
-
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout",
-                        "text_edit_suggestion_item", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
-                new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout",
-                        "text_edit_suggestion_container", true));
-        FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
-                new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle",
-                        "TextAppearance.Holo.SuggestionHighlight", true));
-
-    }
-
-    /** The map adds cookies to each view so that IDE can link xml tags to views. */
-    private final HashMap<View, Object> mViewKeyMap = new HashMap<>();
-    /**
-     * In some cases, when inflating an xml, some objects are created. Then later, the objects are
-     * converted to views. This map stores the mapping from objects to cookies which can then be
-     * used to populate the mViewKeyMap.
-     */
-    private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>();
-    private final BridgeAssetManager mAssets;
-    private Resources mSystemResources;
-    private final Object mProjectKey;
-    private final DisplayMetrics mMetrics;
-    private final RenderResources mRenderResources;
-    private final Configuration mConfig;
-    private final ApplicationInfo mApplicationInfo;
-    private final LayoutlibCallback mLayoutlibCallback;
-    private final WindowManager mWindowManager;
-    private final DisplayManager mDisplayManager;
-    private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
-    private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
-
-    private Resources.Theme mTheme;
-
-    private final Map<Object, PropertiesMap> mDefaultPropMaps = new IdentityHashMap<>();
-
-    // maps for dynamically generated id representing style objects (StyleResourceValue)
-    @Nullable
-    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
-    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
-    private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
-
-    // cache for TypedArray generated from StyleResourceValue object
-    private TypedArrayCache mTypedArrayCache;
-    private BridgeInflater mBridgeInflater;
-
-    private BridgeContentResolver mContentResolver;
-
-    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>();
-    private SharedPreferences mSharedPreferences;
-    private ClassLoader mClassLoader;
-    private IBinder mBinder;
-    private PackageManager mPackageManager;
-    private Boolean mIsThemeAppCompat;
-
-    /**
-     * Some applications that target both pre API 17 and post API 17, set the newer attrs to
-     * reference the older ones. For example, android:paddingStart will resolve to
-     * android:paddingLeft. This way the apps need to only define paddingLeft at any other place.
-     * This a map from value to attribute name. Warning for missing references shouldn't be logged
-     * if value and attr name pair is the same as an entry in this map.
-     */
-    private static Map<String, String> RTL_ATTRS = new HashMap<>(10);
-
-    static {
-        RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
-        RTL_ATTRS.put("?android:attr/paddingRight", "paddingEnd");
-        RTL_ATTRS.put("?android:attr/layout_marginLeft", "layout_marginStart");
-        RTL_ATTRS.put("?android:attr/layout_marginRight", "layout_marginEnd");
-        RTL_ATTRS.put("?android:attr/layout_toLeftOf", "layout_toStartOf");
-        RTL_ATTRS.put("?android:attr/layout_toRightOf", "layout_toEndOf");
-        RTL_ATTRS.put("?android:attr/layout_alignParentLeft", "layout_alignParentStart");
-        RTL_ATTRS.put("?android:attr/layout_alignParentRight", "layout_alignParentEnd");
-        RTL_ATTRS.put("?android:attr/drawableLeft", "drawableStart");
-        RTL_ATTRS.put("?android:attr/drawableRight", "drawableEnd");
-    }
-
-    /**
-     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
-     * @param metrics the {@link DisplayMetrics}.
-     * @param renderResources the configured resources (both framework and projects) for this
-     * render.
-     * @param config the Configuration object for this render.
-     * @param targetSdkVersion the targetSdkVersion of the application.
-     */
-    public BridgeContext(Object projectKey, DisplayMetrics metrics,
-            RenderResources renderResources,
-            AssetRepository assets,
-            LayoutlibCallback layoutlibCallback,
-            Configuration config,
-            int targetSdkVersion,
-            boolean hasRtlSupport) {
-        mProjectKey = projectKey;
-        mMetrics = metrics;
-        mLayoutlibCallback = layoutlibCallback;
-
-        mRenderResources = renderResources;
-        mConfig = config;
-        AssetManager systemAssetManager = AssetManager.getSystem();
-        if (systemAssetManager instanceof BridgeAssetManager) {
-            mAssets = (BridgeAssetManager) systemAssetManager;
-        } else {
-            throw new AssertionError("Creating BridgeContext without initializing Bridge");
-        }
-        mAssets.setAssetRepository(assets);
-
-        mApplicationInfo = new ApplicationInfo();
-        mApplicationInfo.targetSdkVersion = targetSdkVersion;
-        if (hasRtlSupport) {
-            mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
-        }
-
-        mWindowManager = new WindowManagerImpl(mMetrics);
-        mDisplayManager = new DisplayManager(this);
-    }
-
-    /**
-     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
-     * {@link DisplayMetrics}, {@link Configuration}, and {@link LayoutlibCallback}.
-     *
-     * @see #disposeResources()
-     */
-    public void initResources() {
-        AssetManager assetManager = AssetManager.getSystem();
-
-        mSystemResources = Resources_Delegate.initSystem(
-                this,
-                assetManager,
-                mMetrics,
-                mConfig,
-                mLayoutlibCallback);
-        mTheme = mSystemResources.newTheme();
-    }
-
-    /**
-     * Disposes the {@link Resources} singleton.
-     */
-    public void disposeResources() {
-        Resources_Delegate.disposeSystem();
-    }
-
-    public void setBridgeInflater(BridgeInflater inflater) {
-        mBridgeInflater = inflater;
-    }
-
-    public void addViewKey(View view, Object viewKey) {
-        mViewKeyMap.put(view, viewKey);
-    }
-
-    public Object getViewKey(View view) {
-        return mViewKeyMap.get(view);
-    }
-
-    public void addCookie(Object o, Object cookie) {
-        mViewKeyHelpMap.put(o, cookie);
-    }
-
-    public Object getCookie(Object o) {
-        return mViewKeyHelpMap.get(o);
-    }
-
-    public Object getProjectKey() {
-        return mProjectKey;
-    }
-
-    public DisplayMetrics getMetrics() {
-        return mMetrics;
-    }
-
-    public LayoutlibCallback getLayoutlibCallback() {
-        return mLayoutlibCallback;
-    }
-
-    public RenderResources getRenderResources() {
-        return mRenderResources;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return mDefaultPropMaps;
-    }
-
-    public Configuration getConfiguration() {
-        return mConfig;
-    }
-
-    /**
-     * Adds a parser to the stack.
-     * @param parser the parser to add.
-     */
-    public void pushParser(BridgeXmlBlockParser parser) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("PUSH " + parser.getParser().toString());
-        }
-        mParserStack.push(parser);
-    }
-
-    /**
-     * Removes the parser at the top of the stack
-     */
-    public void popParser() {
-        BridgeXmlBlockParser parser = mParserStack.pop();
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("POPD " + parser.getParser().toString());
-        }
-    }
-
-    /**
-     * Returns the current parser at the top the of the stack.
-     * @return a parser or null.
-     */
-    private BridgeXmlBlockParser getCurrentParser() {
-        return mParserStack.peek();
-    }
-
-    /**
-     * Returns the previous parser.
-     * @return a parser or null if there isn't any previous parser
-     */
-    public BridgeXmlBlockParser getPreviousParser() {
-        if (mParserStack.size() < 2) {
-            return null;
-        }
-        return mParserStack.get(mParserStack.size() - 2);
-    }
-
-    public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) {
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resId);
-        boolean isFrameworkRes = true;
-        if (resourceInfo == null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(resId);
-            isFrameworkRes = false;
-        }
-
-        if (resourceInfo == null) {
-            return false;
-        }
-
-        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond(),
-                isFrameworkRes);
-        if (resolveRefs) {
-            value = mRenderResources.resolveResValue(value);
-        }
-
-        if (value == null) {
-            // unable to find the attribute.
-            return false;
-        }
-
-        // check if this is a style resource
-        if (value instanceof StyleResourceValue) {
-            // get the id that will represent this style.
-            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue) value);
-            return true;
-        }
-
-        String stringValue = value.getValue();
-        if (!stringValue.isEmpty()) {
-            if (stringValue.charAt(0) == '#') {
-                outValue.type = TypedValue.TYPE_INT_COLOR_ARGB8;
-                outValue.data = Color.parseColor(value.getValue());
-            }
-            else if (stringValue.charAt(0) == '@') {
-                outValue.type = TypedValue.TYPE_REFERENCE;
-            }
-
-        }
-
-        int a;
-        // if this is a framework value.
-        if (value.isFramework()) {
-            // look for idName in the android R classes.
-            // use 0 a default res value as it's not a valid id value.
-            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        } else {
-            // look for idName in the project R class.
-            // use 0 a default res value as it's not a valid id value.
-            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
-        }
-
-        if (a != 0) {
-            outValue.resourceId = a;
-            return true;
-        }
-
-        // If the value is not a valid reference, fallback to pass the value as a string.
-        outValue.string = stringValue;
-        return true;
-    }
-
-
-    public ResourceReference resolveId(int id) {
-        // first get the String related to this id in the framework
-        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
-
-        if (resourceInfo != null) {
-            return new ResourceReference(resourceInfo.getSecond(), true);
-        }
-
-        // didn't find a match in the framework? look in the project.
-        if (mLayoutlibCallback != null) {
-            resourceInfo = mLayoutlibCallback.resolveResourceId(id);
-
-            if (resourceInfo != null) {
-                return new ResourceReference(resourceInfo.getSecond(), false);
-            }
-        }
-
-        // The base value for R.style is 0x01030000 and the custom style is 0x02030000.
-        // So, if the second byte is 03, it's probably a style.
-        if ((id >> 16 & 0xFF) == 0x03) {
-            return getStyleByDynamicId(id);
-        }
-        return null;
-    }
-
-    public Pair<View, Boolean> inflateView(ResourceReference resource, ViewGroup parent,
-            @SuppressWarnings("SameParameterValue") boolean attachToRoot,
-            boolean skipCallbackParser) {
-        boolean isPlatformLayout = resource.isFramework();
-
-        if (!isPlatformLayout && !skipCallbackParser) {
-            // check if the project callback can provide us with a custom parser.
-            ILayoutPullParser parser = getParser(resource);
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                        this, resource.isFramework());
-                try {
-                    pushParser(blockParser);
-                    return Pair.of(
-                            mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                            Boolean.TRUE);
-                } finally {
-                    popParser();
-                }
-            }
-        }
-
-        ResourceValue resValue;
-        if (resource instanceof ResourceValue) {
-            resValue = (ResourceValue) resource;
-        } else {
-            if (isPlatformLayout) {
-                resValue = mRenderResources.getFrameworkResource(ResourceType.LAYOUT,
-                        resource.getName());
-            } else {
-                resValue = mRenderResources.getProjectResource(ResourceType.LAYOUT,
-                        resource.getName());
-            }
-        }
-
-        if (resValue != null) {
-
-            File xml = new File(resValue.getValue());
-            if (xml.isFile()) {
-                // we need to create a pull parser around the layout XML file, and then
-                // give that to our XmlBlockParser
-                try {
-                    XmlPullParser parser = ParserFactory.create(xml, true);
-
-                    // set the resource ref to have correct view cookies
-                    mBridgeInflater.setResourceReference(resource);
-
-                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(parser,
-                            this, resource.isFramework());
-                    try {
-                        pushParser(blockParser);
-                        return Pair.of(
-                                mBridgeInflater.inflate(blockParser, parent, attachToRoot),
-                                Boolean.FALSE);
-                    } finally {
-                        popParser();
-                    }
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                            "Failed to configure parser for " + xml, e, null /*data*/);
-                    // we'll return null below.
-                } catch (FileNotFoundException e) {
-                    // this shouldn't happen since we check above.
-                } finally {
-                    mBridgeInflater.setResourceReference(null);
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s is missing!", xml), null);
-            }
-        } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
-                            resource.getName()), null);
-        }
-
-        return Pair.of(null, Boolean.FALSE);
-    }
-
-    /**
-     * Returns whether the current selected theme is based on AppCompat
-     */
-    public boolean isAppCompatTheme() {
-        // If a cached value exists, return it.
-        if (mIsThemeAppCompat != null) {
-            return mIsThemeAppCompat;
-        }
-        // Ideally, we should check if the corresponding activity extends
-        // android.support.v7.app.ActionBarActivity, and not care about the theme name at all.
-        StyleResourceValue defaultTheme = mRenderResources.getDefaultTheme();
-        // We can't simply check for parent using resources.themeIsParentOf() since the
-        // inheritance structure isn't really what one would expect. The first common parent
-        // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21).
-        boolean isThemeAppCompat = false;
-        for (int i = 0; i < 50; i++) {
-            if (defaultTheme == null) {
-                break;
-            }
-            // for loop ensures that we don't run into cyclic theme inheritance.
-            if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) {
-                isThemeAppCompat = true;
-                break;
-            }
-            defaultTheme = mRenderResources.getParent(defaultTheme);
-        }
-        mIsThemeAppCompat = isThemeAppCompat;
-        return isThemeAppCompat;
-    }
-
-    @SuppressWarnings("deprecation")
-    private ILayoutPullParser getParser(ResourceReference resource) {
-        ILayoutPullParser parser;
-        if (resource instanceof ResourceValue) {
-            parser = mLayoutlibCallback.getParser((ResourceValue) resource);
-        } else {
-            parser = mLayoutlibCallback.getParser(resource.getName());
-        }
-        return parser;
-    }
-
-    // ------------ Context methods
-
-    @Override
-    public Resources getResources() {
-        return mSystemResources;
-    }
-
-    @Override
-    public Theme getTheme() {
-        return mTheme;
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        // The documentation for this method states that it should return a class loader one can
-        // use to retrieve classes in this package. However, when called by LayoutInflater, we do
-        // not want the class loader to return app's custom views.
-        // This is so that the IDE can instantiate the custom views and also generate proper error
-        // messages in case of failure. This also enables the IDE to fallback to MockView in case
-        // there's an exception thrown when trying to inflate the custom view.
-        // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to
-        // replace invocations of this method to a new method: getFrameworkClassLoader(). Also,
-        // the method is injected into Context. The implementation of getFrameworkClassLoader() is:
-        // "return getClass().getClassLoader();". This means that when LayoutInflater asks for
-        // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have
-        // access to the apps's custom views.
-        // This method can now return the right ClassLoader, which CustomViews can use to do the
-        // right thing.
-        if (mClassLoader == null) {
-            mClassLoader = new ClassLoader(getClass().getClassLoader()) {
-                @Override
-                protected Class<?> findClass(String name) throws ClassNotFoundException {
-                    for (String prefix : BridgeInflater.getClassPrefixList()) {
-                        if (name.startsWith(prefix)) {
-                            // These are framework classes and should not be loaded from the app.
-                            throw new ClassNotFoundException(name + " not found");
-                        }
-                    }
-                    return BridgeContext.this.mLayoutlibCallback.findClass(name);
-                }
-            };
-        }
-        return mClassLoader;
-    }
-
-    @Override
-    public Object getSystemService(String service) {
-        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
-            return mBridgeInflater;
-        }
-
-        if (TEXT_SERVICES_MANAGER_SERVICE.equals(service)) {
-            // we need to return a valid service to avoid NPE
-            return TextServicesManager.getInstance();
-        }
-
-        if (WINDOW_SERVICE.equals(service)) {
-            return mWindowManager;
-        }
-
-        // needed by SearchView
-        if (INPUT_METHOD_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (POWER_SERVICE.equals(service)) {
-            return new PowerManager(this, new BridgePowerManager(), new Handler());
-        }
-
-        if (DISPLAY_SERVICE.equals(service)) {
-            return mDisplayManager;
-        }
-
-        if (ACCESSIBILITY_SERVICE.equals(service)) {
-            return AccessibilityManager.getInstance(this);
-        }
-
-        if (AUTOFILL_MANAGER_SERVICE.equals(service)) {
-            return null;
-        }
-
-        if (AUDIO_SERVICE.equals(service)) {
-            return null;
-        }
-
-        assert false : "Unsupported Service: " + service;
-        return null;
-    }
-
-    @Override
-    public String getSystemServiceName(Class<?> serviceClass) {
-        return SystemServiceRegistry_Accessor.getSystemServiceName(serviceClass);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
-        return obtainStyledAttributes(0, attrs);
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(int resId, int[] attrs)
-            throws Resources.NotFoundException {
-        StyleResourceValue style = null;
-        // get the StyleResourceValue based on the resId;
-        if (resId != 0) {
-            style = getStyleByDynamicId(resId);
-
-            if (style == null) {
-                // In some cases, style may not be a dynamic id, so we do a full search.
-                ResourceReference ref = resolveId(resId);
-                if (ref != null) {
-                    style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
-                }
-            }
-
-            if (style == null) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find style with " + resId, null);
-                return null;
-            }
-        }
-
-        if (mTypedArrayCache == null) {
-            mTypedArrayCache = new TypedArrayCache();
-        }
-
-        List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
-
-        Pair<BridgeTypedArray, PropertiesMap> typeArrayAndPropertiesPair =
-                mTypedArrayCache.get(attrs, currentThemes, resId);
-
-        if (typeArrayAndPropertiesPair == null) {
-            typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs);
-            mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair);
-        }
-        // Add value to defaultPropsMap if needed
-        if (typeArrayAndPropertiesPair.getSecond() != null) {
-            BridgeXmlBlockParser parser = getCurrentParser();
-            Object key = parser != null ? parser.getViewCookie() : null;
-            if (key != null) {
-                PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
-                if (defaultPropMap == null) {
-                    defaultPropMap = typeArrayAndPropertiesPair.getSecond();
-                    mDefaultPropMaps.put(key, defaultPropMap);
-                } else {
-                    defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond());
-                }
-            }
-        }
-        return typeArrayAndPropertiesPair.getFirst();
-    }
-
-    @Override
-    public final BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
-        return obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    @Override
-    public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
-            int defStyleAttr, int defStyleRes) {
-
-        PropertiesMap defaultPropMap = null;
-        boolean isPlatformFile = true;
-
-        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
-        if (set instanceof BridgeXmlBlockParser) {
-            BridgeXmlBlockParser parser;
-            parser = (BridgeXmlBlockParser)set;
-
-            isPlatformFile = parser.isPlatformFile();
-
-            Object key = parser.getViewCookie();
-            if (key != null) {
-                defaultPropMap = mDefaultPropMaps.computeIfAbsent(key, k -> new PropertiesMap());
-            }
-
-        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
-            // this is only for temp layout params generated dynamically, so this is never
-            // platform content.
-            isPlatformFile = false;
-        } else if (set != null) { // null parser is ok
-            // really this should not be happening since its instantiated in Bridge
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Parser is not a BridgeXmlBlockParser!", null);
-            return null;
-        }
-
-        List<Pair<String, Boolean>> attributeList = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, isPlatformFile);
-
-        // look for a custom style.
-        String customStyle = null;
-        if (set != null) {
-            customStyle = set.getAttributeValue(null, "style");
-        }
-
-        StyleResourceValue customStyleValues = null;
-        if (customStyle != null) {
-            ResourceValue item = mRenderResources.findResValue(customStyle,
-                    isPlatformFile /*forceFrameworkOnly*/);
-
-            // resolve it in case it links to something else
-            item = mRenderResources.resolveResValue(item);
-
-            if (item instanceof StyleResourceValue) {
-                customStyleValues = (StyleResourceValue)item;
-            }
-        }
-
-        // resolve the defStyleAttr value into a IStyleResourceValue
-        StyleResourceValue defStyleValues = null;
-
-        if (defStyleAttr != 0) {
-            // get the name from the int.
-            Pair<String, Boolean> defStyleAttribute = searchAttr(defStyleAttr);
-
-            if (defStyleAttribute == null) {
-                // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
-                // This will happen if the user explicitly used a non existing int value for
-                // defStyleAttr or there's something wrong with the project structure/build.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                        "Failed to find the style corresponding to the id " + defStyleAttr, null);
-            } else {
-                String defStyleName = defStyleAttribute.getFirst();
-
-                // look for the style in the current theme, and its parent:
-                ResourceValue item = mRenderResources.findItemInTheme(defStyleName,
-                        defStyleAttribute.getSecond());
-
-                if (item != null) {
-                    // item is a reference to a style entry. Search for it.
-                    item = mRenderResources.findResValue(item.getValue(), item.isFramework());
-                    item = mRenderResources.resolveResValue(item);
-                    if (item instanceof StyleResourceValue) {
-                        defStyleValues = (StyleResourceValue) item;
-                    }
-                    if (defaultPropMap != null) {
-                        if (defStyleAttribute.getSecond()) {
-                            defStyleName = "android:" + defStyleName;
-                        }
-                        defaultPropMap.put("style", new Property(defStyleName, item.getValue()));
-                    }
-                } else {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                            String.format(
-                                    "Failed to find style '%s' in current theme",
-                                    defStyleAttribute.getFirst()),
-                            null);
-                }
-            }
-        } else if (defStyleRes != 0) {
-            StyleResourceValue item = getStyleByDynamicId(defStyleRes);
-            if (item != null) {
-                defStyleValues = item;
-            } else {
-                boolean isFrameworkRes = true;
-                Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
-                if (value == null) {
-                    value = mLayoutlibCallback.resolveResourceId(defStyleRes);
-                    isFrameworkRes = false;
-                }
-
-                if (value != null) {
-                    if ((value.getFirst() == ResourceType.STYLE)) {
-                        // look for the style in all resources:
-                        item = mRenderResources.getStyle(value.getSecond(), isFrameworkRes);
-                        if (item != null) {
-                            if (defaultPropMap != null) {
-                                String name = item.getName();
-                                defaultPropMap.put("style", new Property(name, name));
-                            }
-
-                            defStyleValues = item;
-                        } else {
-                            Bridge.getLog().error(null,
-                                    String.format(
-                                            "Style with id 0x%x (resolved to '%s') does not exist.",
-                                            defStyleRes, value.getSecond()),
-                                    null);
-                        }
-                    } else {
-                        Bridge.getLog().error(null,
-                                String.format(
-                                        "Resource id 0x%x is not of type STYLE (instead %s)",
-                                        defStyleRes, value.getFirst().toString()),
-                                null);
-                    }
-                } else {
-                    Bridge.getLog().error(null,
-                            String.format(
-                                    "Failed to find style with id 0x%x in current theme",
-                                    defStyleRes),
-                            null);
-                }
-            }
-        }
-
-        String appNamespace = mLayoutlibCallback.getNamespace();
-
-        if (attributeList != null) {
-            for (int index = 0 ; index < attributeList.size() ; index++) {
-                Pair<String, Boolean> attribute = attributeList.get(index);
-
-                if (attribute == null) {
-                    continue;
-                }
-
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                String value = null;
-                if (set != null) {
-                    value = set.getAttributeValue(
-                            frameworkAttr ? BridgeConstants.NS_RESOURCES : appNamespace,
-                                    attrName);
-
-                    // if this is an app attribute, and the first get fails, try with the
-                    // new res-auto namespace as well
-                    if (!frameworkAttr && value == null) {
-                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, attrName);
-                    }
-                }
-
-                // Calculate the default value from the Theme in two cases:
-                //   - If defaultPropMap is not null, get the default value to add it to the list
-                //   of default values of properties.
-                //   - If value is null, it means that the attribute is not directly set as an
-                //   attribute in the XML so try to get the default value.
-                ResourceValue defaultValue = null;
-                if (defaultPropMap != null || value == null) {
-                    // look for the value in the custom style first (and its parent if needed)
-                    if (customStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(customStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // then look for the value in the default Style (and its parent if needed)
-                    if (defaultValue == null && defStyleValues != null) {
-                        defaultValue = mRenderResources.findItemInStyle(defStyleValues, attrName,
-                                frameworkAttr);
-                    }
-
-                    // if the item is not present in the defStyle, we look in the main theme (and
-                    // its parent themes)
-                    if (defaultValue == null) {
-                        defaultValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        String preResolve = defaultValue.getValue();
-                        defaultValue = mRenderResources.resolveResValue(defaultValue);
-
-                        if (defaultPropMap != null) {
-                            defaultPropMap.put(
-                                    frameworkAttr ? SdkConstants.PREFIX_ANDROID + attrName :
-                                            attrName, new Property(preResolve, defaultValue.getValue()));
-                        }
-                    }
-                }
-                // Done calculating the defaultValue
-
-                // if there's no direct value for this attribute in the XML, we look for default
-                // values in the widget defStyle, and then in the theme.
-                if (value == null) {
-                    if (frameworkAttr) {
-                        // For some framework values, layoutlib patches the actual value in the
-                        // theme when it helps to improve the final preview. In most cases
-                        // we just disable animations.
-                        ResourceValue patchedValue = FRAMEWORK_PATCHED_VALUES.get(attrName);
-                        if (patchedValue != null) {
-                            defaultValue = patchedValue;
-                        }
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (defaultValue != null) {
-                        // If the value is a reference to another theme attribute that doesn't
-                        // exist, we should log a warning and omit it.
-                        String val = defaultValue.getValue();
-                        if (val != null && val.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                            // Because we always use the latest framework code, some resources might
-                            // fail to resolve when using old themes (they haven't been backported).
-                            // Since this is an artifact caused by us using always the latest
-                            // code, we check for some of those values and replace them here.
-                            defaultValue = FRAMEWORK_REPLACE_VALUES.get(attrName);
-
-                            if (defaultValue == null &&
-                                    (getApplicationInfo().targetSdkVersion < JELLY_BEAN_MR1 ||
-                                    !attrName.equals(RTL_ATTRS.get(val)))) {
-                                // Only log a warning if the referenced value isn't one of the RTL
-                                // attributes, or the app targets old API.
-                                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
-                                        String.format("Failed to find '%s' in current theme.", val),
-                                        val);
-                            }
-                        }
-                    }
-
-                    ta.bridgeSetValue(index, attrName, frameworkAttr, defaultValue);
-                } else {
-                    // there is a value in the XML, but we need to resolve it in case it's
-                    // referencing another resource or a theme value.
-                    ta.bridgeSetValue(index, attrName, frameworkAttr,
-                            mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return Looper.myLooper();
-    }
-
-
-    @Override
-    public String getPackageName() {
-        if (mApplicationInfo.packageName == null) {
-            mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
-        }
-        return mApplicationInfo.packageName;
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        if (mPackageManager == null) {
-            mPackageManager = new BridgePackageManager();
-        }
-        return mPackageManager;
-    }
-
-    // ------------- private new methods
-
-    /**
-     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
-     * values found in the given style. If no style is specified, the default theme, along with the
-     * styles applied to it are used.
-     *
-     * @see #obtainStyledAttributes(int, int[])
-     */
-    private Pair<BridgeTypedArray, PropertiesMap> createStyleBasedTypedArray(
-            @Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
-        List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
-
-        BridgeTypedArray ta =
-                Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
-
-        PropertiesMap defaultPropMap = new PropertiesMap();
-        // for each attribute, get its name so that we can search it in the style
-        for (int i = 0; i < attrs.length; i++) {
-            Pair<String, Boolean> attribute = attributes.get(i);
-
-            if (attribute != null) {
-                // look for the value in the given style
-                ResourceValue resValue;
-                String attrName = attribute.getFirst();
-                boolean frameworkAttr = attribute.getSecond();
-                if (style != null) {
-                    resValue = mRenderResources.findItemInStyle(style, attrName, frameworkAttr);
-                } else {
-                    resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
-                }
-
-                if (resValue != null) {
-                    // Add it to defaultPropMap before resolving
-                    String preResolve = resValue.getValue();
-                    // resolve it to make sure there are no references left.
-                    resValue = mRenderResources.resolveResValue(resValue);
-                    ta.bridgeSetValue(i, attrName, frameworkAttr, resValue);
-                    defaultPropMap.put(
-                            frameworkAttr ? SdkConstants.ANDROID_PREFIX + attrName : attrName,
-                            new Property(preResolve, resValue.getValue()));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return Pair.of(ta, defaultPropMap);
-    }
-
-    /**
-     * The input int[] attrs is a list of attributes. The returns a list of information about
-     * each attributes. The information is (name, isFramework)
-     * <p/>
-     *
-     * @param attrs An attribute array reference given to obtainStyledAttributes.
-     * @return List of attribute information.
-     */
-    private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
-        List<Pair<String, Boolean>> results = new ArrayList<>(attrs.length);
-
-        // for each attribute, get its name so that we can search it in the style
-        for (int attr : attrs) {
-            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attr);
-            boolean isFramework = false;
-            if (resolvedResource != null) {
-                isFramework = true;
-            } else {
-                resolvedResource = mLayoutlibCallback.resolveResourceId(attr);
-            }
-
-            if (resolvedResource != null) {
-                results.add(Pair.of(resolvedResource.getSecond(), isFramework));
-            } else {
-                results.add(null);
-            }
-        }
-
-        return results;
-    }
-
-    /**
-     * Searches for the attribute referenced by its internal id.
-     *
-     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
-     * @return A (name, isFramework) pair describing the attribute if found. Returns null
-     *         if nothing is found.
-     */
-    private Pair<String, Boolean> searchAttr(int attr) {
-        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.TRUE);
-        }
-
-        info = mLayoutlibCallback.resolveResourceId(attr);
-        if (info != null) {
-            return Pair.of(info.getSecond(), Boolean.FALSE);
-        }
-
-        return null;
-    }
-
-    public int getDynamicIdByStyle(StyleResourceValue resValue) {
-        if (mDynamicIdToStyleMap == null) {
-            // create the maps.
-            mDynamicIdToStyleMap = new HashMap<>();
-            mStyleToDynamicIdMap = new HashMap<>();
-        }
-
-        // look for an existing id
-        Integer id = mStyleToDynamicIdMap.get(resValue);
-
-        if (id == null) {
-            // generate a new id
-            id = ++mDynamicIdGenerator;
-
-            // and add it to the maps.
-            mDynamicIdToStyleMap.put(id, resValue);
-            mStyleToDynamicIdMap.put(resValue, id);
-        }
-
-        return id;
-    }
-
-    private StyleResourceValue getStyleByDynamicId(int i) {
-        if (mDynamicIdToStyleMap != null) {
-            return mDynamicIdToStyleMap.get(i);
-        }
-
-        return null;
-    }
-
-    public int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
-        if (getRenderResources().getFrameworkResource(resType, resName) != null) {
-            // Bridge.getResourceId creates a new resource id if an existing one isn't found. So,
-            // we check for the existence of the resource before calling it.
-            return Bridge.getResourceId(resType, resName);
-        }
-
-        return defValue;
-    }
-
-    public int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
-        // getResourceId creates a new resource id if an existing resource id isn't found. So, we
-        // check for the existence of the resource before calling it.
-        if (getRenderResources().getProjectResource(resType, resName) != null) {
-            if (mLayoutlibCallback != null) {
-                Integer value = mLayoutlibCallback.getResourceId(resType, resName);
-                if (value != null) {
-                    return value;
-                }
-            }
-        }
-
-        return defValue;
-    }
-
-    public static Context getBaseContext(Context context) {
-        while (context instanceof ContextWrapper) {
-            context = ((ContextWrapper) context).getBaseContext();
-        }
-        return context;
-    }
-
-    public IBinder getBinder() {
-        if (mBinder == null) {
-            // create a dummy binder. We only need it be not null.
-            mBinder = new IBinder() {
-                @Override
-                public String getInterfaceDescriptor() throws RemoteException {
-                    return null;
-                }
-
-                @Override
-                public boolean pingBinder() {
-                    return false;
-                }
-
-                @Override
-                public boolean isBinderAlive() {
-                    return false;
-                }
-
-                @Override
-                public IInterface queryLocalInterface(String descriptor) {
-                    return null;
-                }
-
-                @Override
-                public void dump(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
-
-                }
-
-                @Override
-                public boolean transact(int code, Parcel data, Parcel reply, int flags)
-                        throws RemoteException {
-                    return false;
-                }
-
-                @Override
-                public void linkToDeath(DeathRecipient recipient, int flags)
-                        throws RemoteException {
-
-                }
-
-                @Override
-                public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
-                    return false;
-                }
-
-                @Override
-                public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
-                  String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver) {
-                }
-            };
-        }
-        return mBinder;
-    }
-
-    //------------ NOT OVERRIDEN --------------------
-
-    @Override
-    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public int checkCallingOrSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkCallingUriPermission(Uri arg0, int arg1) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkSelfPermission(String arg0) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
-            int arg4, int arg5) {
-        // pass
-        return 0;
-    }
-
-    @Override
-    public void clearWallpaper() {
-        // pass
-
-    }
-
-    @Override
-    public Context createPackageContext(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createConfigurationContext(Configuration overrideConfiguration) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createDisplayContext(Display display) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createContextForSplit(String splitName) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String[] databaseList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createApplicationContext(ApplicationInfo application, int flags)
-            throws PackageManager.NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean moveDatabaseFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteDatabase(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteFile(String arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
-            String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingPermission(String arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
-            String arg4) {
-        // pass
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
-            int arg3, int arg4, int arg5, String arg6) {
-        // pass
-
-    }
-
-    @Override
-    public String[] fileList() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public BridgeAssetManager getAssets() {
-        return mAssets;
-    }
-
-    @Override
-    public File getCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getCodeCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalCacheDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getPreloadsFileCache() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        if (mContentResolver == null) {
-            mContentResolver = new BridgeContentResolver(this);
-        }
-        return mContentResolver;
-    }
-
-    @Override
-    public File getDatabasePath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDir(String arg0, int arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFileStreamPath(String arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getSharedPreferencesPath(String name) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getDataDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getNoBackupFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getExternalFilesDir(String type) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getPackageCodePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getBasePackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public String getOpPackageName() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo() {
-        return mApplicationInfo;
-    }
-
-    @Override
-    public String getPackageResourcePath() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(File arg0, int arg1) {
-        if (mSharedPreferences == null) {
-            mSharedPreferences = new BridgeSharedPreferences();
-        }
-        return mSharedPreferences;
-    }
-
-    @Override
-    public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public boolean deleteSharedPreferences(String name) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public Drawable getWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        return -1;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        return -1;
-    }
-
-    @Override
-    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
-            CursorFactory arg2, DatabaseErrorHandler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Drawable peekWallpaper() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1, int arg2) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3, int arg4) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiverAsUser(BroadcastReceiver arg0, UserHandle arg0p5,
-            IntentFilter arg1, String arg2, Handler arg3) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void removeStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(Uri arg0, int arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void revokeUriPermission(String arg0, Uri arg1, int arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) {
-        // pass
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // pass
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
-            String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission) {
-        // pass
-    }
-
-    @Override
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, Bundle options) {
-        // pass
-    }
-
-    public void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
-            Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcast(Intent arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcast(Intent intent,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
-           Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
-        // pass
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcastAsUser(Intent intent,
-            UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras) {
-        // pass
-    }
-
-    @Override
-    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
-        // pass
-    }
-
-    @Override
-    public void setTheme(int arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(Bitmap arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void setWallpaper(InputStream arg0) throws IOException {
-        // pass
-
-    }
-
-    @Override
-    public void startActivity(Intent arg0) {
-        // pass
-    }
-
-    @Override
-    public void startActivity(Intent arg0, Bundle arg1) {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
-            Bundle options) throws IntentSender.SendIntentException {
-        // pass
-    }
-
-    @Override
-    public boolean startInstrumentation(ComponentName arg0, String arg1,
-            Bundle arg2) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startService(Intent arg0) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundService(Intent service) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopService(Intent arg0) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public ComponentName startServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
-        // pass
-        return false;
-    }
-
-    @Override
-    public void unbindService(ServiceConnection arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void unregisterReceiver(BroadcastReceiver arg0) {
-        // pass
-
-    }
-
-    @Override
-    public Context getApplicationContext() {
-        return this;
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0) {
-        // pass
-
-    }
-
-    @Override
-    public void startActivities(Intent[] arg0, Bundle arg1) {
-        // pass
-
-    }
-
-    @Override
-    public boolean isRestricted() {
-        return false;
-    }
-
-    @Override
-    public File getObbDir() {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
-        return null;
-    }
-
-    @Override
-    public DisplayAdjustments getDisplayAdjustments(int displayId) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Display getDisplay() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void updateDisplay(int displayId) {
-        // pass
-    }
-
-    @Override
-    public int getUserId() {
-        return 0; // not used
-    }
-
-    @Override
-    public File[] getExternalFilesDirs(String type) {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getObbDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalCacheDirs() {
-        // pass
-        return new File[0];
-    }
-
-    @Override
-    public File[] getExternalMediaDirs() {
-        // pass
-        return new File[0];
-    }
-
-    public void setScrollYPos(@NonNull View view, int scrollPos) {
-        mScrollYPos.put(view, scrollPos);
-    }
-
-    public int getScrollYPos(@NonNull View view) {
-        Integer pos = mScrollYPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    public void setScrollXPos(@NonNull View view, int scrollPos) {
-        mScrollXPos.put(view, scrollPos);
-    }
-
-    public int getScrollXPos(@NonNull View view) {
-        Integer pos = mScrollXPos.get(view);
-        return pos != null ? pos : 0;
-    }
-
-    @Override
-    public Context createDeviceProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public Context createCredentialProtectedStorageContext() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public boolean isDeviceProtectedStorage() {
-        return false;
-    }
-
-    @Override
-    public boolean isCredentialProtectedStorage() {
-        return false;
-    }
-
-    /**
-     * The cached value depends on
-     * <ol>
-     * <li>{@code int[]}: the attributes for which TypedArray is created </li>
-     * <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of
-     * creation of the TypedArray</li>
-     * <li>{@code Integer}: the default style used at the time of creation</li>
-     * </ol>
-     *
-     * The class is created by using nested maps resolving one dependency at a time.
-     * <p/>
-     * The final value of the nested maps is a pair of the typed array and a map of properties
-     * that should be added to {@link #mDefaultPropMaps}, if needed.
-     */
-    private static class TypedArrayCache {
-
-        private Map<int[],
-                Map<List<StyleResourceValue>,
-                        Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>> mCache;
-
-        private TypedArrayCache() {
-            mCache = new IdentityHashMap<>();
-        }
-
-        public Pair<BridgeTypedArray, PropertiesMap> get(int[] attrs,
-                List<StyleResourceValue> themes, int resId) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.get(attrs);
-            if (cacheFromThemes != null) {
-                Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                        cacheFromThemes.get(themes);
-                if (cacheFromResId != null) {
-                    return cacheFromResId.get(resId);
-                }
-            }
-            return null;
-        }
-
-        public void put(int[] attrs, List<StyleResourceValue> themes, int resId,
-                Pair<BridgeTypedArray, PropertiesMap> value) {
-            Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
-                    cacheFromThemes = mCache.computeIfAbsent(attrs, k -> new HashMap<>());
-            Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
-                    cacheFromThemes.computeIfAbsent(themes, k -> new HashMap<>());
-            cacheFromResId.put(resId, value);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
deleted file mode 100644
index 4805ed1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.internal.inputmethod.IInputContentUriToken;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.InputBindResult;
-
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.text.style.SuggestionSpan;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSubtype;
-
-import java.util.List;
-
-/**
- * Basic implementation of IInputMethodManager that does nothing.
- *
- */
-public class BridgeIInputMethodManager implements IInputMethodManager {
-
-    @Override
-    public void addClient(IInputMethodClient arg0, IInputContext arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void finishInput(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public InputMethodSubtype getCurrentInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getEnabledInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
-            boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List<InputMethodInfo> getInputMethodList() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public InputMethodSubtype getLastInputMethodSubtype() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public List getShortcutInputMethodsAndSubtypes() throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void hideMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean hideSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean notifySuggestionPicked(SuggestionSpan arg0, String arg1, int arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void registerSuggestionSpansForNotification(SuggestionSpan[] arg0)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void removeClient(IInputMethodClient arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean setCurrentInputMethodSubtype(InputMethodSubtype arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void setImeWindowStatus(IBinder arg0, IBinder arg1, int arg2, int arg3)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setInputMethod(IBinder arg0, String arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setInputMethodAndSubtype(IBinder arg0, String arg1, InputMethodSubtype arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean setInputMethodEnabled(String arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void showInputMethodAndSubtypeEnablerFromClient(IInputMethodClient arg0, String arg1)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showInputMethodPickerFromClient(IInputMethodClient arg0,
-            int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void showMySoftInput(IBinder arg0, int arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public boolean showSoftInput(IInputMethodClient arg0, int arg1, ResultReceiver arg2)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToLastInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean switchToNextInputMethod(IBinder arg0, boolean arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-     public int getInputMethodWindowVisibleHeight() throws RemoteException {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void notifyUserAction(int sequenceNumber) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void clearLastInputMethodWindowForTransition(IBinder arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public InputBindResult startInputOrWindowGainedFocus(
-            /* @InputMethodClient.StartInputReason */ int startInputReason,
-            IInputMethodClient client, IBinder windowToken, int controlFlags,
-            /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
-            int windowFlags, EditorInfo attribute, IInputContext inputContext,
-            /* @InputConnectionInspector.MissingMethodFlags */ int missingMethodFlags)
-            throws RemoteException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public IInputContentUriToken createInputContentUriToken(IBinder token, Uri contentUri,
-            String packageName) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void reportFullscreenMode(IBinder token, boolean fullscreen) {
-        // TODO Auto-generated method stub
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
deleted file mode 100644
index f5912e7..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.BridgeConstants;
-
-import android.util.AttributeSet;
-
-import java.util.Map;
-
-/**
- * An implementation of the {@link AttributeSet} interface on top of a map of attribute in the form
- * of (name, value).
- *
- * This is meant to be called only from {@link BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * in the case of LayoutParams and therefore isn't a full implementation.
- */
-public class BridgeLayoutParamsMapAttributes implements AttributeSet {
-
-    private final Map<String, String> mAttributes;
-
-    public BridgeLayoutParamsMapAttributes(Map<String, String> attributes) {
-        mAttributes = attributes;
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
-            return mAttributes.get(name);
-        }
-
-        return null;
-    }
-
-    // ---- the following methods are not called from
-    // BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
-    // Should they ever be called, we'll just implement them on a need basis.
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getPositionDescription() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute,
-            int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute,
-            float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeListValue(int index,
-            String[] options, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getClassAttribute() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
deleted file mode 100644
index 47dad34..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PackageInstallObserver;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ChangedPackages;
-import android.content.pm.InstantAppInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageInstallObserver;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.IntentFilterVerificationInfo;
-import android.content.pm.KeySet;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageItemInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.SharedLibraryInfo;
-import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.VersionedPackage;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.os.storage.VolumeInfo;
-import java.util.List;
-
-/**
- * An implementation of {@link PackageManager} that does nothing.
- */
-@SuppressWarnings("deprecation")
-public class BridgePackageManager extends PackageManager {
-    @Override
-    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public PackageInfo getPackageInfo(VersionedPackage versionedPackage,
-            @PackageInfoFlags int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibraries(@InstallFlags int flags) {
-        return null;
-    }
-
-    @Override
-    public List<SharedLibraryInfo> getSharedLibrariesAsUser(@InstallFlags int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public String[] currentToCanonicalPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public String[] canonicalToCurrentPackageNames(String[] names) {
-        return new String[0];
-    }
-
-    @Override
-    public Intent getLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
-        return null;
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException {
-        return new int[0];
-    }
-
-    @Override
-    public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int getPackageUidAsUser(String packageName, int flags, int userHandle) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public PermissionInfo getPermissionInfo(String name, int flags) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public boolean isPermissionReviewModeEnabled() {
-        return false;
-    }
-
-    @Override
-    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo(String packageName, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getActivityInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ActivityInfo getReceiverInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ServiceInfo getServiceInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo getProviderInfo(ComponentName component, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public int checkPermission(String permName, String pkgName) {
-        return 0;
-    }
-
-    @Override
-    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
-        return false;
-    }
-
-    @Override
-    public String getPermissionControllerPackageName() {
-        return null;
-    }
-
-    @Override
-    public boolean addPermission(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public boolean addPermissionAsync(PermissionInfo info) {
-        return false;
-    }
-
-    @Override
-    public void removePermission(String name) {
-    }
-
-    @Override
-    public void grantRuntimePermission(String packageName, String permissionName, UserHandle user) {
-    }
-
-    @Override
-    public void revokeRuntimePermission(String packageName, String permissionName,
-            UserHandle user) {
-    }
-
-    @Override
-    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
-        return 0;
-    }
-
-    @Override
-    public void updatePermissionFlags(String permissionName, String packageName, int flagMask,
-            int flagValues, UserHandle user) {
-    }
-
-    @Override
-    public boolean shouldShowRequestPermissionRationale(String permission) {
-        return false;
-    }
-
-    @Override
-    public int checkSignatures(String pkg1, String pkg2) {
-        return 0;
-    }
-
-    @Override
-    public int checkSignatures(int uid1, int uid2) {
-        return 0;
-    }
-
-    @Override
-    public String[] getPackagesForUid(int uid) {
-        return new String[0];
-    }
-
-    @Override
-    public String getNameForUid(int uid) {
-        return null;
-    }
-
-    @Override
-    public int getUidForSharedUser(String sharedUserName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplications(int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<InstantAppInfo> getInstantApps() {
-        return null;
-    }
-
-    @Override
-    public Drawable getInstantAppIcon(String packageName) {
-        assert false : "Unsupported operation";
-        return new ColorDrawable();
-    }
-
-    @Override
-    public byte[] getInstantAppCookie() {
-        return new byte[0];
-    }
-
-    @Override
-    public boolean isInstantApp() {
-        return false;
-    }
-
-    @Override
-    public boolean isInstantApp(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxBytes() {
-        return 0;
-    }
-
-    @Override
-    public int getInstantAppCookieMaxSize() {
-        return 0;
-    }
-
-    @Override
-    public void clearInstantAppCookie() {;
-
-    }
-
-    @Override
-    public void updateInstantAppCookie(@Nullable byte[] cookie) {
-
-    }
-
-    @Override
-    public boolean setInstantAppCookie(@NonNull byte[] cookie) {
-        return false;
-    }
-
-    @Override
-    public String[] getSystemSharedLibraryNames() {
-        return new String[0];
-    }
-
-    @Override
-    public String getServicesSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public @NonNull String getSharedSystemSharedLibraryPackageName() {
-        return null;
-    }
-
-    @Override
-    public FeatureInfo[] getSystemAvailableFeatures() {
-        return new FeatureInfo[0];
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name) {
-        return false;
-    }
-
-    @Override
-    public boolean hasSystemFeature(String name, int version) {
-        return false;
-    }
-
-    @Override
-    public ResolveInfo resolveActivity(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
-            Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public ResolveInfo resolveService(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
-            int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProvider(String name, int flags) {
-        return null;
-    }
-
-    @Override
-    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
-        return null;
-    }
-
-    @Override
-    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
-        return null;
-    }
-
-    @Override
-    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
-        return null;
-    }
-
-    @Override
-    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getDefaultActivityIcon() {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Drawable getApplicationLogo(String packageName) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
-            Rect badgeLocation, int badgeDensity) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public CharSequence getApplicationLabel(ApplicationInfo info) {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForActivity(ComponentName activityName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplication(String appPackageName)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
-            throws NameNotFoundException {
-        return null;
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags,
-            String installerPackageName) {
-    }
-
-    @Override
-    public int installExistingPackage(String packageName) throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public int installExistingPackageAsUser(String packageName, int userId)
-            throws NameNotFoundException {
-        return 0;
-    }
-
-    @Override
-    public void verifyPendingInstall(int id, int verificationCode) {
-    }
-
-    @Override
-    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
-            long millisecondsToDelay) {
-    }
-
-    @Override
-    public void verifyIntentFilter(int verificationId, int verificationCode,
-            List<String> outFailedDomains) {
-    }
-
-    @Override
-    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
-        return 0;
-    }
-
-    @Override
-    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
-        return false;
-    }
-
-    @Override
-    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
-        return null;
-    }
-
-    @Override
-    public List<IntentFilter> getAllIntentFilters(String packageName) {
-        return null;
-    }
-
-    @Override
-    public String getDefaultBrowserPackageNameAsUser(int userId) {
-        return null;
-    }
-
-    @Override
-    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
-    }
-
-    @Override
-    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
-    }
-
-    @Override
-    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
-    }
-
-    @Override
-    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
-            int userId) {
-    }
-
-    @Override
-    public String getInstallerPackageName(String packageName) {
-        return null;
-    }
-
-    @Override
-    public void clearApplicationUserData(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
-            IPackageDataObserver observer) {
-    }
-
-    @Override
-    public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
-    }
-
-    @Override
-    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
-            IPackageStatsObserver observer) {
-    }
-
-    @Override
-    public void addPackageToPreferred(String packageName) {
-    }
-
-    @Override
-    public void removePackageFromPreferred(String packageName) {
-    }
-
-    @Override
-    public List<PackageInfo> getPreferredPackages(int flags) {
-        return null;
-    }
-
-    @Override
-    public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set,
-            ComponentName activity) {
-    }
-
-    @Override
-    public void clearPackagePreferredActivities(String packageName) {
-    }
-
-    @Override
-    public int getPreferredActivities(List<IntentFilter> outFilters,
-            List<ComponentName> outActivities, String packageName) {
-        return 0;
-    }
-
-    @Override
-    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
-        return null;
-    }
-
-    @Override
-    public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
-    }
-
-    @Override
-    public int getComponentEnabledSetting(ComponentName componentName) {
-        return 0;
-    }
-
-    @Override
-    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
-    }
-
-    @Override
-    public int getApplicationEnabledSetting(String packageName) {
-        return 0;
-    }
-
-    @Override
-    public void flushPackageRestrictionsAsUser(int userId) {
-    }
-
-    @Override
-    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
-            UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle userHandle) {
-        return false;
-    }
-
-    @Override
-    public boolean isSafeMode() {
-        return false;
-    }
-
-    @Override
-    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
-    }
-
-    @Override
-    public KeySet getKeySetByAlias(String packageName, String alias) {
-        return null;
-    }
-
-    @Override
-    public KeySet getSigningKeySet(String packageName) {
-        return null;
-    }
-
-    @Override
-    public boolean isSignedBy(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public boolean isSignedByExactly(String packageName, KeySet ks) {
-        return false;
-    }
-
-    @Override
-    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
-            int userId) {
-        return new String[]{};
-    }
-
-    @Override
-    public boolean isPackageSuspendedForUser(String packageName, int userId) {
-        return false;
-    }
-
-    @Override
-    public void setApplicationCategoryHint(String packageName, int categoryHint) {
-    }
-
-    @Override
-    public int getMoveStatus(int moveId) {
-        return 0;
-    }
-
-    @Override
-    public void registerMoveCallback(MoveCallback callback, Handler handler) {
-    }
-
-    @Override
-    public void unregisterMoveCallback(MoveCallback callback) {
-    }
-
-    @Override
-    public int movePackage(String packageName, VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
-        return null;
-    }
-
-    @Override
-    public int movePrimaryStorage(VolumeInfo vol) {
-        return 0;
-    }
-
-    @Override
-    public VolumeInfo getPrimaryStorageCurrentVolume() {
-        return null;
-    }
-
-    @Override
-    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
-        return null;
-    }
-
-    @Override
-    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
-        return null;
-    }
-
-    @Override
-    public ChangedPackages getChangedPackages(int sequenceNumber) {
-        return null;
-    }
-
-    @Override
-    public boolean isUpgrade() {
-        return false;
-    }
-
-    @Override
-    public PackageInstaller getPackageInstaller() {
-        return null;
-    }
-
-    @Override
-    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
-            int flags) {
-    }
-
-    @Override
-    public void clearCrossProfileIntentFilters(int sourceUserId) {
-    }
-
-    @Override
-    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
-        return null;
-    }
-
-    @Override
-    public boolean isPackageAvailable(String packageName) {
-        return false;
-    }
-
-    @Override
-    public int getInstallReason(String packageName, UserHandle user) {
-        return INSTALL_REASON_UNKNOWN;
-    }
-
-    @Override
-    public boolean canRequestPackageInstalls() {
-        return false;
-    }
-
-    @Override
-    public ComponentName getInstantAppResolverSettingsComponent() {
-        return null;
-    }
-
-    @Override
-    public ComponentName getInstantAppInstallerComponent() {
-        return null;
-    }
-
-    @Override
-    public String getInstantAppAndroidId(String packageName, UserHandle user) {
-        return null;
-    }
-
-    @Override
-    public void registerDexModule(String dexModulePath,
-            @Nullable DexModuleRegisterCallback callback) {
-        callback.onDexModuleRegistered(dexModulePath, false, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
deleted file mode 100644
index ed428ec9..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.PowerSaveState;
-import android.os.RemoteException;
-import android.os.WorkSource;
-
-/**
- * Fake implementation of IPowerManager.
- *
- */
-public class BridgePowerManager implements IPowerManager {
-
-    @Override
-    public boolean isInteractive() throws RemoteException {
-        return true;
-    }
-
-    @Override
-    public boolean isPowerSaveMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean setPowerSaveMode(boolean mode) throws RemoteException {
-        return false;
-    }
-
-    public PowerSaveState getPowerSaveState(int serviceType) {
-        return null;
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void powerHint(int hintId, int data) {
-        // pass for now.
-    }
-
-    @Override
-    public void crash(String arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void goToSleep(long arg0, int arg1, int arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void nap(long arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void reboot(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void rebootSafeMode(boolean confirm, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void shutdown(boolean confirm, String reason, boolean wait) {
-        // pass for now.
-    }
-
-    @Override
-    public void releaseWakeLock(IBinder arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setAttentionLight(boolean arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(float arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTemporaryScreenBrightnessSettingOverride(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setStayOnSetting(int arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void updateWakeLockWorkSource(IBinder arg0, WorkSource arg1, String arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isWakeLockLevelSupported(int level) throws RemoteException {
-        // pass for now.
-        return true;
-    }
-
-    @Override
-    public void userActivity(long time, int event, int flags) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void wakeUp(long time, String reason, String opPackageName) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void boostScreenBrightness(long time) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean isDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isLightDeviceIdleMode() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public boolean isScreenBrightnessBoosted() throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public int getLastShutdownReason() {
-        return PowerManager.SHUTDOWN_REASON_UNKNOWN;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
deleted file mode 100644
index 132ff2f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeSharedPreferences.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.SharedPreferences;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * An empty shared preferences implementation which doesn't store anything. It always returns
- * null, 0 or false.
- */
-public class BridgeSharedPreferences implements SharedPreferences {
-    private Editor mEditor;
-
-    @Override
-    public Map<String, ?> getAll() {
-        return null;
-    }
-
-    @Override
-    public String getString(String key, String defValue) {
-        return null;
-    }
-
-    @Override
-    public Set<String> getStringSet(String key, Set<String> defValues) {
-        return null;
-    }
-
-    @Override
-    public int getInt(String key, int defValue) {
-        return 0;
-    }
-
-    @Override
-    public long getLong(String key, long defValue) {
-        return 0;
-    }
-
-    @Override
-    public float getFloat(String key, float defValue) {
-        return 0;
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return false;
-    }
-
-    @Override
-    public boolean contains(String key) {
-        return false;
-    }
-
-    @Override
-    public Editor edit() {
-        if (mEditor != null) {
-            return mEditor;
-        }
-        mEditor = new Editor() {
-            @Override
-            public Editor putString(String key, String value) {
-                return null;
-            }
-
-            @Override
-            public Editor putStringSet(String key, Set<String> values) {
-                return null;
-            }
-
-            @Override
-            public Editor putInt(String key, int value) {
-                return null;
-            }
-
-            @Override
-            public Editor putLong(String key, long value) {
-                return null;
-            }
-
-            @Override
-            public Editor putFloat(String key, float value) {
-                return null;
-            }
-
-            @Override
-            public Editor putBoolean(String key, boolean value) {
-                return null;
-            }
-
-            @Override
-            public Editor remove(String key) {
-                return null;
-            }
-
-            @Override
-            public Editor clear() {
-                return null;
-            }
-
-            @Override
-            public boolean commit() {
-                return false;
-            }
-
-            @Override
-            public void apply() {
-            }
-        };
-        return mEditor;
-    }
-
-    @Override
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-
-    @Override
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
deleted file mode 100644
index ffbe7c4..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.internal.os.IResultReceiver;
-
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.DragEvent;
-import android.view.IWindow;
-
-/**
- * Implementation of {@link IWindow} to pass to the AttachInfo.
- */
-public final class BridgeWindow implements IWindow {
-
-    @Override
-    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchGetNewSurface() throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
-            boolean b, MergedConfiguration mergedConfig, Rect rect7, boolean b2, boolean b3, int i0)
-            throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void moved(int arg0, int arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-            boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWallpaperCommand(String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-    }
-
-    @Override
-    public void closeSystemDialogs(String reason) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchDragEvent(DragEvent event) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(float x, float y) {
-        // pass for now
-    }
-
-    @Override
-    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
-            int localValue, int localChanges) {
-        // pass for now.
-    }
-
-    @Override
-    public void dispatchWindowShown() {
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            IResultReceiver receiver, int deviceId) throws RemoteException {
-    }
-
-    @Override
-    public void dispatchPointerCaptureChanged(boolean hasCapture) {
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
deleted file mode 100644
index 2c88394..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import android.content.ClipData;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.MergedConfiguration;
-import android.view.IWindow;
-import android.view.IWindowId;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.WindowManager.LayoutParams;
-
-/**
- * Implementation of {@link IWindowSession} so that mSession is not null in
- * the {@link SurfaceView}.
- */
-public final class BridgeWindowSession implements IWindowSession {
-
-    @Override
-    public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3, Rect arg4,
-            InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplay(IWindow arg0, int seq, LayoutParams arg1, int arg2, int displayId,
-                            Rect arg3, Rect arg4, Rect arg5, InputChannel outInputchannel)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                      Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public int addToDisplayWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2,
-                                               int displayId, Rect arg3, Rect arg4)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public void finishDrawing(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public boolean getInTouchMode() throws RemoteException {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-        // pass for now.
-        return false;
-    }
-
-    @Override
-    public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
-            int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
-            Rect rect6, Rect rect7, MergedConfiguration mergedConfig, Surface surface)
-            throws RemoteException {
-        // pass for now.
-        return 0;
-    }
-
-    @Override
-    public boolean outOfMemory(IWindow window) throws RemoteException {
-        return false;
-    }
-
-    @Override
-    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-        // pass for now.
-    }
-
-    @Override
-    public void remove(IWindow arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInTouchMode(boolean arg0) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
-    public void setInsets(IWindow window, int touchable, Rect contentInsets,
-            Rect visibleInsets, Region touchableRegion) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder prepareDrag(IWindow window, int flags,
-            int thumbnailWidth, int thumbnailHeight, Surface outSurface)
-            throws RemoteException {
-        // pass for now
-        return null;
-    }
-
-    @Override
-    public boolean performDrag(IWindow window, IBinder dragToken,
-            int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-            ClipData data)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public boolean startMovingTask(IWindow window, float startX, float startY)
-            throws RemoteException {
-        // pass for now
-        return false;
-    }
-
-    @Override
-    public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void cancelDragAndDrop(IBinder dragToken) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientEntered(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void dragRecipientExited(IWindow window) throws RemoteException {
-        // pass for now
-    }
-
-    @Override
-    public void setWallpaperPosition(IBinder window, float x, float y,
-        float xStep, float yStep) {
-        // pass for now.
-    }
-
-    @Override
-    public void wallpaperOffsetsComplete(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void setWallpaperDisplayOffset(IBinder windowToken, int x, int y) {
-        // pass for now.
-    }
-
-    @Override
-    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-            int z, Bundle extras, boolean sync) {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void wallpaperCommandComplete(IBinder window, Bundle result) {
-        // pass for now.
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void onRectangleOnScreenRequested(IBinder window, Rect rectangle) {
-        // pass for now.
-    }
-
-    @Override
-    public IWindowId getWindowId(IBinder window) throws RemoteException {
-        // pass for now.
-        return null;
-    }
-
-    @Override
-    public void pokeDrawLock(IBinder window) {
-        // pass for now.
-    }
-
-    @Override
-    public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
-        // pass for now.
-    }
-
-    @Override
-    public void updatePointerIcon(IWindow window) {
-        // pass for now.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
deleted file mode 100644
index ac8712e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.XmlResourceParser;
-import android.util.AttributeSet;
-import android.util.BridgeXmlPullAttributes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * {@link BridgeXmlBlockParser} reimplements most of android.xml.XmlBlock.Parser.
- * It delegates to both an instance of {@link XmlPullParser} and an instance of
- * XmlPullAttributes (for the {@link AttributeSet} part).
- */
-public class BridgeXmlBlockParser implements XmlResourceParser {
-
-    private final XmlPullParser mParser;
-    private final BridgeXmlPullAttributes mAttrib;
-    private final BridgeContext mContext;
-    private final boolean mPlatformFile;
-
-    private boolean mStarted = false;
-    private int mEventType = START_DOCUMENT;
-
-    private boolean mPopped = true; // default to true in case it's not pushed.
-
-    /**
-     * Builds a {@link BridgeXmlBlockParser}.
-     * @param parser The XmlPullParser to get the content from.
-     * @param context the Context.
-     * @param platformFile Indicates whether the the file is a platform file or not.
-     */
-    public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("CRTE " + parser.toString());
-        }
-
-        mParser = parser;
-        mContext = context;
-        mPlatformFile = platformFile;
-        mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
-
-        if (mContext != null) {
-            mContext.pushParser(this);
-            mPopped = false;
-        }
-    }
-
-    public XmlPullParser getParser() {
-        return mParser;
-    }
-
-    public boolean isPlatformFile() {
-        return mPlatformFile;
-    }
-
-    public Object getViewCookie() {
-        if (mParser instanceof ILayoutPullParser) {
-            return ((ILayoutPullParser)mParser).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void ensurePopped() {
-        if (mContext != null && mPopped == false) {
-            mContext.popParser();
-            mPopped = true;
-        }
-    }
-
-    // ------- XmlResourceParser implementation
-
-    @Override
-    public void setFeature(String name, boolean state)
-            throws XmlPullParserException {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
-            return;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
-            return;
-        }
-        throw new XmlPullParserException("Unsupported feature: " + name);
-    }
-
-    @Override
-    public boolean getFeature(String name) {
-        if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
-            return true;
-        }
-        if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void setProperty(String name, Object value) throws XmlPullParserException {
-        throw new XmlPullParserException("setProperty() not supported");
-    }
-
-    @Override
-    public Object getProperty(String name) {
-        return null;
-    }
-
-    @Override
-    public void setInput(Reader in) throws XmlPullParserException {
-        mParser.setInput(in);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String inputEncoding)
-            throws XmlPullParserException {
-        mParser.setInput(inputStream, inputEncoding);
-    }
-
-    @Override
-    public void defineEntityReplacementText(String entityName,
-            String replacementText) throws XmlPullParserException {
-        throw new XmlPullParserException(
-                "defineEntityReplacementText() not supported");
-    }
-
-    @Override
-    public String getNamespacePrefix(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespacePrefix() not supported");
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return null;
-    }
-
-    @Override
-    public String getNamespace(String prefix) {
-        throw new RuntimeException("getNamespace() not supported");
-    }
-
-    @Override
-    public int getNamespaceCount(int depth) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceCount() not supported");
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return "Binary XML file line #" + getLineNumber();
-    }
-
-    @Override
-    public String getNamespaceUri(int pos) throws XmlPullParserException {
-        throw new XmlPullParserException("getNamespaceUri() not supported");
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return -1;
-    }
-
-    @Override
-    public int getDepth() {
-        return mParser.getDepth();
-    }
-
-    @Override
-    public String getText() {
-        return mParser.getText();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mParser.getLineNumber();
-    }
-
-    @Override
-    public int getEventType() {
-        return mEventType;
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        // Original comment: whitespace was stripped by aapt.
-        return mParser.isWhitespace();
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new RuntimeException("getPrefix not supported");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] holderForStartAndLength) {
-        String txt = getText();
-        char[] chars = null;
-        if (txt != null) {
-            holderForStartAndLength[0] = 0;
-            holderForStartAndLength[1] = txt.length();
-            chars = new char[txt.length()];
-            txt.getChars(0, txt.length(), chars, 0);
-        }
-        return chars;
-    }
-
-    @Override
-    public String getNamespace() {
-        return mParser.getNamespace();
-    }
-
-    @Override
-    public String getName() {
-        return mParser.getName();
-    }
-
-    @Override
-    public String getAttributeNamespace(int index) {
-        return mParser.getAttributeNamespace(index);
-    }
-
-    @Override
-    public String getAttributeName(int index) {
-        return mParser.getAttributeName(index);
-    }
-
-    @Override
-    public String getAttributePrefix(int index) {
-        throw new RuntimeException("getAttributePrefix not supported");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() {
-        // XXX Need to detect this.
-        return false;
-    }
-
-    @Override
-    public int getAttributeCount() {
-        return mParser.getAttributeCount();
-    }
-
-    @Override
-    public String getAttributeValue(int index) {
-        return mParser.getAttributeValue(index);
-    }
-
-    @Override
-    public String getAttributeType(int index) {
-        return "CDATA";
-    }
-
-    @Override
-    public boolean isAttributeDefault(int index) {
-        return false;
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        return next();
-    }
-
-    @Override
-    public String getAttributeValue(String namespace, String name) {
-        return mParser.getAttributeValue(namespace, name);
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        if (!mStarted) {
-            mStarted = true;
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("STRT " + mParser.toString());
-            }
-
-            return START_DOCUMENT;
-        }
-
-        int ev = mParser.next();
-
-        if (ParserFactory.LOG_PARSER) {
-            System.out.println("NEXT " + mParser.toString() + " " +
-                    eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
-        }
-
-        if (ev == END_TAG && mParser.getDepth() == 1) {
-            // done with parser remove it from the context stack.
-            ensurePopped();
-
-            if (ParserFactory.LOG_PARSER) {
-                System.out.println("");
-            }
-        }
-
-        mEventType = ev;
-        return ev;
-    }
-
-    public static String eventTypeToString(int eventType) {
-        switch (eventType) {
-            case START_DOCUMENT:
-                return "START_DOC";
-            case END_DOCUMENT:
-                return "END_DOC";
-            case START_TAG:
-                return "START_TAG";
-            case END_TAG:
-                return "END_TAG";
-            case TEXT:
-                return "TEXT";
-            case CDSECT:
-                return "CDSECT";
-            case ENTITY_REF:
-                return "ENTITY_REF";
-            case IGNORABLE_WHITESPACE:
-                return "IGNORABLE_WHITESPACE";
-            case PROCESSING_INSTRUCTION:
-                return "PROCESSING_INSTRUCTION";
-            case COMMENT:
-                return "COMMENT";
-            case DOCDECL:
-                return "DOCDECL";
-        }
-
-        return "????";
-    }
-
-    @Override
-    public void require(int type, String namespace, String name)
-            throws XmlPullParserException {
-        if (type != getEventType()
-                || (namespace != null && !namespace.equals(getNamespace()))
-                || (name != null && !name.equals(getName())))
-            throw new XmlPullParserException("expected " + TYPES[type]
-                    + getPositionDescription());
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        if (getEventType() != START_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG to read next text", this,
-                    null);
-        }
-        int eventType = next();
-        if (eventType == TEXT) {
-            String result = getText();
-            eventType = next();
-            if (eventType != END_TAG) {
-                throw new XmlPullParserException(
-                        getPositionDescription()
-                                + ": event TEXT it must be immediately followed by END_TAG",
-                        this, null);
-            }
-            return result;
-        } else if (eventType == END_TAG) {
-            return "";
-        } else {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": parser must be on START_TAG or TEXT to read text",
-                    this, null);
-        }
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        int eventType = next();
-        if (eventType == TEXT && isWhitespace()) { // skip whitespace
-            eventType = next();
-        }
-        if (eventType != START_TAG && eventType != END_TAG) {
-            throw new XmlPullParserException(getPositionDescription()
-                    + ": expected start or end tag", this, null);
-        }
-        return eventType;
-    }
-
-    // AttributeSet implementation
-
-
-    @Override
-    public void close() {
-        // pass
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(index, defaultValue);
-    }
-
-    @Override
-    public boolean getAttributeBooleanValue(String namespace, String attribute,
-            boolean defaultValue) {
-        return mAttrib.getAttributeBooleanValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(int index, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(index, defaultValue);
-    }
-
-    @Override
-    public float getAttributeFloatValue(String namespace, String attribute, float defaultValue) {
-        return mAttrib.getAttributeFloatValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(int index, String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(index, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeListValue(String namespace, String attribute,
-            String[] options, int defaultValue) {
-        return mAttrib.getAttributeListValue(namespace, attribute, options, defaultValue);
-    }
-
-    @Override
-    public int getAttributeNameResource(int index) {
-        return mAttrib.getAttributeNameResource(index);
-    }
-
-    @Override
-    public int getAttributeResourceValue(int index, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeResourceValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(index, defaultValue);
-    }
-
-    @Override
-    public int getAttributeUnsignedIntValue(String namespace, String attribute, int defaultValue) {
-        return mAttrib.getAttributeUnsignedIntValue(namespace, attribute, defaultValue);
-    }
-
-    @Override
-    public String getClassAttribute() {
-        return mAttrib.getClassAttribute();
-    }
-
-    @Override
-    public String getIdAttribute() {
-        return mAttrib.getIdAttribute();
-    }
-
-    @Override
-    public int getIdAttributeResourceValue(int defaultValue) {
-        return mAttrib.getIdAttributeResourceValue(defaultValue);
-    }
-
-    @Override
-    public int getStyleAttribute() {
-        return mAttrib.getStyleAttribute();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
deleted file mode 100644
index 051de90..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-
-/**
- * This contains all known keys for the {@link RenderParams#getFlag(Key)}.
- * <p/>
- * The IDE has its own copy of this class which may be newer or older than this one.
- * <p/>
- * Constants should never be modified or removed from this class.
- */
-public final class RenderParamsFlags {
-
-    public static final Key<String> FLAG_KEY_ROOT_TAG =
-            new Key<String>("rootTag", String.class);
-    public static final Key<Boolean> FLAG_KEY_DISABLE_BITMAP_CACHING =
-            new Key<Boolean>("disableBitmapCaching", Boolean.class);
-    public static final Key<Boolean> FLAG_KEY_RENDER_ALL_DRAWABLE_STATES =
-            new Key<Boolean>("renderAllDrawableStates", Boolean.class);
-    /**
-     * To tell LayoutLib that the IDE supports RecyclerView.
-     * <p/>
-     * Default is false.
-     */
-    public static final Key<Boolean> FLAG_KEY_RECYCLER_VIEW_SUPPORT =
-            new Key<Boolean>("recyclerViewSupport", Boolean.class);
-    /**
-     * The application package name. Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<String> FLAG_KEY_APPLICATION_PACKAGE =
-            new Key<String>("applicationPackage", String.class);
-    /**
-     * To tell LayoutLib that IDE supports providing XML Parser for a file (useful for getting in
-     * memory contents of the file). Used via {@link LayoutlibCallback#getFlag(Key)}
-     */
-    public static final Key<Boolean> FLAG_KEY_XML_FILE_PARSER_SUPPORT =
-            new Key<Boolean>("xmlFileParser", Boolean.class);
-    /**
-     * To tell LayoutLib to not render when creating a new session. This allows controlling when the first
-     * layout rendering will happen.
-     */
-    public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE =
-            new Key<Boolean>("doNotRenderOnCreate", Boolean.class);
-
-    // Disallow instances.
-    private RenderParamsFlags() {}
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
deleted file mode 100644
index 131aa17..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/graphics/NopCanvas.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.graphics;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.NinePatch;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Picture;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-/**
- * Canvas implementation that does not do any rendering
- */
-public class NopCanvas extends Canvas {
-    private boolean mIsInitialized = false;
-
-    public NopCanvas() {
-        super();
-        mIsInitialized = true;
-    }
-
-    @Override
-    public boolean isHardwareAccelerated() {
-        // We return true the first time so there are no allocations for the software renderer in
-        // the constructor
-        return !mIsInitialized;
-    }
-
-    @Override
-    public int save() {
-        return 0;
-    }
-
-    @Override
-    public int save(int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(RectF bounds, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
-            int saveFlags) {
-        return 0;
-    }
-
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha) {
-        return 0;
-    }
-
-    @Override
-    public void restore() {
-    }
-
-    @Override
-    public int getSaveCount() {
-        return 0;
-    }
-
-    @Override
-    public void restoreToCount(int saveCount) {
-    }
-
-    @Override
-    public void drawRGB(int r, int g, int b) {
-    }
-
-    @Override
-    public void drawARGB(int a, int r, int g, int b) {
-    }
-
-    @Override
-    public void drawColor(int color) {
-    }
-
-    @Override
-    public void drawColor(int color, Mode mode) {
-    }
-
-    @Override
-    public void drawPaint(Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawPoints(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawPoint(float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, int offset, int count, Paint paint) {
-    }
-
-    @Override
-    public void drawLines(float[] pts, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(RectF rect, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(Rect r, Paint paint) {
-    }
-
-    @Override
-    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(RectF oval, Paint paint) {
-    }
-
-    @Override
-    public void drawOval(float left, float top, float right, float bottom, Paint paint) {
-    }
-
-    @Override
-    public void drawCircle(float cx, float cy, float radius, Paint paint) {
-    }
-
-    @Override
-    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawArc(float left, float top, float right, float bottom, float startAngle,
-            float sweepAngle, boolean useCenter, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-    }
-
-    @Override
-    public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
-            Paint paint) {
-    }
-
-    @Override
-    public void drawPath(Path path, Paint paint) {
-    }
-
-    @Override
-    protected void throwIfCannotDraw(Bitmap bitmap) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-    }
-
-    @Override
-    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
-            int vertOffset, int[] colors, int colorOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
-            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
-            int indexOffset, int indexCount, Paint paint) {
-    }
-
-    @Override
-    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
-            float x, float y, boolean isRtl, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawPosText(String text, float[] pos, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
-            float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, RectF dst) {
-    }
-
-    @Override
-    public void drawPicture(Picture picture, Rect dst) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
deleted file mode 100644
index aa873a6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with the design support lib.
- */
-public class DesignLibUtil {
-
-    private static final String PKG_PREFIX = "android.support.design.widget.";
-    public static final String CN_COORDINATOR_LAYOUT = PKG_PREFIX + "CoordinatorLayout";
-    public static final String CN_APPBAR_LAYOUT = PKG_PREFIX + "AppBarLayout";
-    public static final String CN_COLLAPSING_TOOLBAR_LAYOUT =
-            PKG_PREFIX + "CollapsingToolbarLayout";
-    public static final String CN_TOOLBAR = "android.support.v7.widget.Toolbar";
-    public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
-
-    /**
-     * Tries to set the title of a view. This is used to set the title in a
-     * CollapsingToolbarLayout.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setTitle(@NonNull View view, @Nullable String title) {
-        if (title == null) {
-            return;
-        }
-        try {
-            invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title);
-        } catch (ReflectionException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,
-                    "Error occurred while trying to set title.", e);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
deleted file mode 100644
index 40d3811..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.Nullable;
-import android.view.View;
-
-import static android.view.Gravity.END;
-import static android.view.Gravity.LEFT;
-import static android.view.Gravity.RIGHT;
-import static android.view.Gravity.START;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-public class DrawerLayoutUtil {
-
-    public static final String CN_DRAWER_LAYOUT = "android.support.v4.widget.DrawerLayout";
-
-    public static void openDrawer(View drawerLayout, @Nullable String drawerGravity) {
-        int gravity = -1;
-        if ("left".equals(drawerGravity)) {
-            gravity = LEFT;
-        } else if ("right".equals(drawerGravity)) {
-            gravity = RIGHT;
-        } else if ("start".equals(drawerGravity)) {
-            gravity = START;
-        } else if ("end".equals(drawerGravity)) {
-            gravity = END;
-        }
-        if (gravity > 0) {
-            openDrawer(drawerLayout, gravity);
-        }
-    }
-
-    private static void openDrawer(View drawerLayout, int gravity) {
-        try {
-            invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout,
-                    gravity);
-        } catch (ReflectionException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
-                    getCause(e), null);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
deleted file mode 100644
index ab27819..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.util.ReflectionUtils;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.View;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Utility class for working with android.support.v7.widget.RecyclerView
- */
-public class RecyclerViewUtil {
-
-    private static final String RV_PKG_PREFIX = "android.support.v7.widget.";
-    public static final String CN_RECYCLER_VIEW = RV_PKG_PREFIX + "RecyclerView";
-    private static final String CN_LAYOUT_MANAGER = CN_RECYCLER_VIEW + "$LayoutManager";
-    private static final String CN_ADAPTER = CN_RECYCLER_VIEW + "$Adapter";
-
-    // LinearLayoutManager related constants.
-    private static final String CN_LINEAR_LAYOUT_MANAGER = RV_PKG_PREFIX + "LinearLayoutManager";
-    private static final Class<?>[] LLM_CONSTRUCTOR_SIGNATURE = new Class<?>[]{Context.class};
-
-    /**
-     * Tries to create an Adapter ({@code android.support.v7.widget.RecyclerView.Adapter} and a
-     * LayoutManager {@code RecyclerView.LayoutManager} and assign these to the {@code RecyclerView}
-     * that is passed.
-     * <p/>
-     * Any exceptions thrown during the process are logged in {@link Bridge#getLog()}
-     */
-    public static void setAdapter(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback layoutlibCallback, int adapterLayout) {
-        try {
-            setLayoutManager(recyclerView, context, layoutlibCallback);
-            Object adapter = createAdapter(layoutlibCallback);
-            if (adapter != null) {
-                setProperty(recyclerView, CN_ADAPTER, adapter, "setAdapter");
-                setProperty(adapter, int.class, adapterLayout, "setLayoutId");
-            }
-        } catch (ReflectionException e) {
-            Throwable cause = getCause(e);
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                    "Error occurred while trying to setup RecyclerView.", cause, null);
-        }
-    }
-
-    private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
-            @NonNull LayoutlibCallback callback) throws ReflectionException {
-        if (getLayoutManager(recyclerView) == null) {
-            // Only set the layout manager if not already set by the recycler view.
-            Object layoutManager = createLayoutManager(context, callback);
-            if (layoutManager != null) {
-                setProperty(recyclerView, CN_LAYOUT_MANAGER, layoutManager, "setLayoutManager");
-            }
-        }
-    }
-
-    /** Creates a LinearLayoutManager using the provided context. */
-    @Nullable
-    private static Object createLayoutManager(@NonNull Context context,
-            @NonNull LayoutlibCallback callback)
-            throws ReflectionException {
-        try {
-            return callback.loadView(CN_LINEAR_LAYOUT_MANAGER, LLM_CONSTRUCTOR_SIGNATURE,
-                    new Object[]{context});
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @Nullable
-    private static Object getLayoutManager(View recyclerView) throws ReflectionException {
-        return invoke(getMethod(recyclerView.getClass(), "getLayoutManager"), recyclerView);
-    }
-
-    @Nullable
-    private static Object createAdapter(@NonNull LayoutlibCallback layoutlibCallback)
-            throws ReflectionException {
-        Boolean ideSupport =
-                layoutlibCallback.getFlag(RenderParamsFlags.FLAG_KEY_RECYCLER_VIEW_SUPPORT);
-        if (ideSupport != Boolean.TRUE) {
-            return null;
-        }
-        try {
-            return layoutlibCallback.loadClass(CN_ADAPTER, new Class[0], new Object[0]);
-        } catch (Exception e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull String propertyClassName,
-      @NonNull Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        Class<?> propertyClass = ReflectionUtils.getClassInstance(propertyValue, propertyClassName);
-        setProperty(object, propertyClass, propertyValue, propertySetter);
-    }
-
-    private static void setProperty(@NonNull Object object, @NonNull Class<?> propertyClass,
-            @Nullable Object propertyValue, @NonNull String propertySetter)
-            throws ReflectionException {
-        invoke(getMethod(object.getClass(), propertySetter, propertyClass), object, propertyValue);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
deleted file mode 100644
index 6ad9efc..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android.support;
-
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-import android.widget.ScrollView;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getAccessibleMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getClassInstance;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
-
-/**
- * Class with utility methods to instantiate Preferences provided by the support library.
- * This class uses reflection to access the support preference objects so it heavily depends on
- * the API being stable.
- */
-public class SupportPreferencesUtil {
-    private static final String PREFERENCE_PKG = "android.support.v7.preference";
-    private static final String PREFERENCE_MANAGER = PREFERENCE_PKG + ".PreferenceManager";
-    private static final String PREFERENCE_GROUP = PREFERENCE_PKG + ".PreferenceGroup";
-    private static final String PREFERENCE_GROUP_ADAPTER =
-      PREFERENCE_PKG + ".PreferenceGroupAdapter";
-    private static final String PREFERENCE_INFLATER = PREFERENCE_PKG + ".PreferenceInflater";
-
-    private SupportPreferencesUtil() {
-    }
-
-    @NonNull
-    private static Object instantiateClass(@NonNull LayoutlibCallback callback,
-            @NonNull String className, @Nullable Class[] constructorSignature,
-            @Nullable Object[] constructorArgs) throws ReflectionException {
-        try {
-            Object instance = callback.loadClass(className, constructorSignature, constructorArgs);
-            if (instance == null) {
-                throw new ClassNotFoundException(className + " class not found");
-            }
-            return instance;
-        } catch (ClassNotFoundException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    private static Object createPreferenceGroupAdapter(@NonNull LayoutlibCallback callback,
-            @NonNull Object preferenceScreen) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-
-        return instantiateClass(callback, PREFERENCE_GROUP_ADAPTER,
-                new Class[]{preferenceGroupClass}, new Object[]{preferenceScreen});
-    }
-
-    @NonNull
-    private static Object createInflatedPreference(@NonNull LayoutlibCallback callback,
-      @NonNull Context context, @NonNull XmlPullParser parser, @NonNull Object preferenceScreen,
-      @NonNull Object preferenceManager) throws ReflectionException {
-        Class<?> preferenceGroupClass = getClassInstance(preferenceScreen, PREFERENCE_GROUP);
-        Object preferenceInflater = instantiateClass(callback, PREFERENCE_INFLATER,
-          new Class[]{Context.class, preferenceManager.getClass()},
-          new Object[]{context, preferenceManager});
-        Object inflatedPreference =
-                invoke(getAccessibleMethod(preferenceInflater.getClass(), "inflate",
-                        XmlPullParser.class, preferenceGroupClass), preferenceInflater, parser,
-                        null);
-
-        if (inflatedPreference == null) {
-            throw new ReflectionException("inflate method returned null");
-        }
-
-        return inflatedPreference;
-    }
-
-    /**
-     * Returns a themed wrapper context of {@link BridgeContext} with the theme specified in
-     * ?attr/preferenceTheme applied to it.
-     */
-    @Nullable
-    private static Context getThemedContext(@NonNull BridgeContext bridgeContext) {
-        RenderResources resources = bridgeContext.getRenderResources();
-        ResourceValue preferenceTheme = resources.findItemInTheme("preferenceTheme", false);
-
-        if (preferenceTheme != null) {
-            // resolve it, if needed.
-            preferenceTheme = resources.resolveResValue(preferenceTheme);
-        }
-        if (preferenceTheme instanceof StyleResourceValue) {
-            int styleId = bridgeContext.getDynamicIdByStyle(((StyleResourceValue) preferenceTheme));
-            if (styleId != 0) {
-                return new ContextThemeWrapper(bridgeContext, styleId);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link LinearLayout} containing all the UI widgets representing the preferences
-     * passed in the group adapter.
-     */
-    @Nullable
-    private static LinearLayout setUpPreferencesListView(@NonNull BridgeContext bridgeContext,
-            @NonNull Context themedContext, @NonNull ArrayList<Object> viewCookie,
-            @NonNull Object preferenceGroupAdapter) throws ReflectionException {
-        // Setup the LinearLayout that will contain the preferences
-        LinearLayout listView = new LinearLayout(themedContext);
-        listView.setOrientation(LinearLayout.VERTICAL);
-        listView.setLayoutParams(
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
-
-        if (!viewCookie.isEmpty()) {
-            bridgeContext.addViewKey(listView, viewCookie.get(0));
-        }
-
-        // Get all the preferences and add them to the LinearLayout
-        Integer preferencesCount =
-                (Integer) invoke(getMethod(preferenceGroupAdapter.getClass(), "getItemCount"),
-                        preferenceGroupAdapter);
-        if (preferencesCount == null) {
-            return listView;
-        }
-
-        Method getItemId = getMethod(preferenceGroupAdapter.getClass(), "getItemId", int.class);
-        Method getItemViewType =
-                getMethod(preferenceGroupAdapter.getClass(), "getItemViewType", int.class);
-        Method onCreateViewHolder =
-                getMethod(preferenceGroupAdapter.getClass(), "onCreateViewHolder", ViewGroup.class,
-                        int.class);
-        for (int i = 0; i < preferencesCount; i++) {
-            Long id = (Long) invoke(getItemId, preferenceGroupAdapter, i);
-            if (id == null) {
-                continue;
-            }
-
-            // Get the type of the preference layout and bind it to a newly created view holder
-            Integer type = (Integer) invoke(getItemViewType, preferenceGroupAdapter, i);
-            Object viewHolder =
-                    invoke(onCreateViewHolder, preferenceGroupAdapter, listView, type);
-            if (viewHolder == null) {
-                continue;
-            }
-            invoke(getMethod(preferenceGroupAdapter.getClass(), "onBindViewHolder",
-                    viewHolder.getClass(), int.class), preferenceGroupAdapter, viewHolder, i);
-
-            try {
-                // Get the view from the view holder and add it to our layout
-                View itemView =
-                        (View) viewHolder.getClass().getField("itemView").get(viewHolder);
-
-                int arrayPosition = id.intValue() - 1; // IDs are 1 based
-                if (arrayPosition >= 0 && arrayPosition < viewCookie.size()) {
-                    bridgeContext.addViewKey(itemView, viewCookie.get(arrayPosition));
-                }
-                listView.addView(itemView);
-            } catch (IllegalAccessException | NoSuchFieldException ignored) {
-            }
-        }
-
-        return listView;
-    }
-
-    /**
-     * Inflates a preferences layout using the support library. If the support library is not
-     * available, this method will return null without advancing the parsers.
-     */
-    @Nullable
-    public static View inflatePreference(@NonNull BridgeContext bridgeContext,
-            @NonNull XmlPullParser parser, @Nullable ViewGroup root) {
-        try {
-            LayoutlibCallback callback = bridgeContext.getLayoutlibCallback();
-
-            Context context = getThemedContext(bridgeContext);
-            if (context == null) {
-                // Probably we couldn't find the "preferenceTheme" in the theme
-                return null;
-            }
-
-            // Create PreferenceManager
-            Object preferenceManager =
-                    instantiateClass(callback, PREFERENCE_MANAGER, new Class[]{Context.class},
-                            new Object[]{context});
-
-            // From this moment on, we can assume that we found the support library and that
-            // nothing should fail
-
-            // Create PreferenceScreen
-            Object preferenceScreen =
-                    invoke(getMethod(preferenceManager.getClass(), "createPreferenceScreen",
-                            Context.class), preferenceManager, context);
-            if (preferenceScreen == null) {
-                return null;
-            }
-
-            // Setup a parser that stores the list of cookies in the same order as the preferences
-            // are inflated. That way we can later reconstruct the list using the preference id
-            // since they are sequential and start in 1.
-            ArrayList<Object> viewCookie = new ArrayList<>();
-            if (parser instanceof BridgeXmlBlockParser) {
-                // Setup a parser that stores the XmlTag
-                parser = new BridgeXmlBlockParser(parser, null, false) {
-                    @Override
-                    public Object getViewCookie() {
-                        return ((BridgeXmlBlockParser) getParser()).getViewCookie();
-                    }
-
-                    @Override
-                    public int next() throws XmlPullParserException, IOException {
-                        int ev = super.next();
-                        if (ev == XmlPullParser.START_TAG) {
-                            viewCookie.add(this.getViewCookie());
-                        }
-
-                        return ev;
-                    }
-                };
-            }
-
-            // Create the PreferenceInflater
-            Object inflatedPreference =
-              createInflatedPreference(callback, context, parser, preferenceScreen,
-                preferenceManager);
-
-            // Setup the RecyclerView (set adapter and layout manager)
-            Object preferenceGroupAdapter =
-                    createPreferenceGroupAdapter(callback, inflatedPreference);
-
-            // Instead of just setting the group adapter as adapter for a RecyclerView, we manually
-            // get all the items and add them to a LinearLayout. This allows us to set the view
-            // cookies so the preferences are correctly linked to their XML.
-            LinearLayout listView = setUpPreferencesListView(bridgeContext, context, viewCookie,
-                    preferenceGroupAdapter);
-
-            ScrollView scrollView = new ScrollView(context);
-            scrollView.setLayoutParams(
-              new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-            scrollView.addView(listView);
-
-            if (root != null) {
-                root.addView(scrollView);
-            }
-
-            return scrollView;
-        } catch (ReflectionException e) {
-            return null;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
deleted file mode 100644
index d7d16cf..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.layoutlib.bridge.android.view;
-
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.Display.Mode;
-import android.view.DisplayAdjustments;
-import android.view.DisplayInfo;
-import android.view.View;
-import android.view.WindowManager;
-
-public class WindowManagerImpl implements WindowManager {
-
-    private final DisplayMetrics mMetrics;
-    private final Display mDisplay;
-
-    public WindowManagerImpl(DisplayMetrics metrics) {
-        mMetrics = metrics;
-
-        DisplayInfo info = new DisplayInfo();
-        info.logicalHeight = mMetrics.heightPixels;
-        info.logicalWidth = mMetrics.widthPixels;
-        info.supportedModes = new Mode[] {
-                new Mode(0, mMetrics.widthPixels, mMetrics.heightPixels, 60f)
-        };
-        mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info,
-                DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-    }
-
-    @Override
-    public Display getDefaultDisplay() {
-        return mDisplay;
-    }
-
-
-    @Override
-    public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-    @Override
-    public void removeView(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
-        // pass
-    }
-
-
-    @Override
-    public void removeViewImmediate(View arg0) {
-        // pass
-    }
-
-    @Override
-    public void requestAppKeyboardShortcuts(
-            KeyboardShortcutsReceiver receiver, int deviceId) {
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
deleted file mode 100644
index cdcf0ea..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.ResourceType;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-
-/**
- * Assumes that the AppCompat library is present in the project's classpath and creates an
- * actionbar around it.
- */
-public class AppCompatActionBar extends BridgeActionBar {
-
-    private Object mWindowDecorActionBar;
-    private static final String WINDOW_ACTION_BAR_CLASS = "android.support.v7.internal.app.WindowDecorActionBar";
-    // This is used on v23.1.1 and later.
-    private static final String WINDOW_ACTION_BAR_CLASS_NEW = "android.support.v7.app.WindowDecorActionBar";
-    private Class<?> mWindowActionBarClass;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-        int contentRootId = context.getProjectResourceValue(ResourceType.ID,
-                "action_bar_activity_content", 0);
-        View contentView = getDecorContent().findViewById(contentRootId);
-        if (contentView != null) {
-            assert contentView instanceof FrameLayout;
-            setContentRoot((FrameLayout) contentView);
-        } else {
-            // Something went wrong. Create a new FrameLayout in the enclosing layout.
-            FrameLayout contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        }
-        try {
-            Class[] constructorParams = {View.class};
-            Object[] constructorArgs = {getDecorContent()};
-            LayoutlibCallback callback = params.getLayoutlibCallback();
-
-            // Check if the old action bar class is present.
-            String actionBarClass = WINDOW_ACTION_BAR_CLASS;
-            try {
-                callback.findClass(actionBarClass);
-            } catch (ClassNotFoundException expected) {
-                // Failed to find the old class, use the newer one.
-                actionBarClass = WINDOW_ACTION_BAR_CLASS_NEW;
-            }
-
-            mWindowDecorActionBar = callback.loadView(actionBarClass,
-                    constructorParams, constructorArgs);
-            mWindowActionBarClass = mWindowDecorActionBar == null ? null :
-                    mWindowDecorActionBar.getClass();
-            setupActionBar();
-        } catch (Exception e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
-                    "Failed to load AppCompat ActionBar with unknown error.", e);
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        // We always assume that the app has requested the action bar.
-        return context.getRenderResources().getProjectResource(ResourceType.LAYOUT,
-                "abc_screen_toolbar");
-    }
-
-    @Override
-    protected LayoutInflater getInflater(BridgeContext context) {
-        // Other than the resource resolution part, the code has been taken from the support
-        // library. see code from line 269 onwards in
-        // https://android.googlesource.com/platform/frameworks/support/+/android-5.1.0_r1/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
-        Context themedContext = context;
-        RenderResources resources = context.getRenderResources();
-        ResourceValue actionBarTheme = resources.findItemInTheme("actionBarTheme", false);
-        if (actionBarTheme != null) {
-            // resolve it, if needed.
-            actionBarTheme = resources.resolveResValue(actionBarTheme);
-        }
-        if (actionBarTheme instanceof StyleResourceValue) {
-            int styleId = context.getDynamicIdByStyle(((StyleResourceValue) actionBarTheme));
-            if (styleId != 0) {
-                themedContext = new ContextThemeWrapper(context, styleId);
-            }
-        }
-        return LayoutInflater.from(themedContext);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        if (title != null && mWindowDecorActionBar != null) {
-            Method setTitle = getMethod(mWindowActionBarClass, "setTitle", CharSequence.class);
-            invoke(setTitle, mWindowDecorActionBar, title);
-        }
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        if (subtitle != null && mWindowDecorActionBar != null) {
-            Method setSubtitle = getMethod(mWindowActionBarClass, "setSubtitle", CharSequence.class);
-            invoke(setSubtitle, mWindowDecorActionBar, subtitle);
-        }
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        // Do this only if the action bar doesn't already have an icon.
-        if (icon != null && !icon.isEmpty() && mWindowDecorActionBar != null) {
-            if (invoke(getMethod(mWindowActionBarClass, "hasIcon"), mWindowDecorActionBar)
-                    == Boolean.TRUE) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    Method setIcon = getMethod(mWindowActionBarClass, "setIcon", Drawable.class);
-                    invoke(setIcon, mWindowDecorActionBar, iconDrawable);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        if (mWindowDecorActionBar != null) {
-            Method setHomeAsUp = getMethod(mWindowActionBarClass,
-                    "setDefaultDisplayHomeAsUpEnabled", boolean.class);
-            invoke(setHomeAsUp, mWindowDecorActionBar, homeAsUp);
-        }
-    }
-
-    @Override
-    public void createMenuPopup() {
-        // it's hard to add menus to appcompat's actionbar, since it'll use a lot of reflection.
-        // so we skip it for now.
-    }
-
-    @Nullable
-    private static Method getMethod(Class<?> owner, String name, Class<?>... parameterTypes) {
-        try {
-            return owner == null ? null : owner.getMethod(name, parameterTypes);
-        } catch (NoSuchMethodException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    @Nullable
-    private static Object invoke(Method method, Object owner, Object... args) {
-        try {
-            return method == null ? null : method.invoke(owner, args);
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    // TODO: this is duplicated from FrameworkActionBarWrapper$WindowActionBarWrapper
-    @Nullable
-    private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-        RenderResources res = mBridgeContext.getRenderResources();
-        ResourceValue value = res.findResValue(name, isFramework);
-        value = res.resolveResValue(value);
-        if (value != null) {
-            return ResourceHelper.getDrawable(value, mBridgeContext);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
deleted file mode 100644
index a439e7d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.MockView;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.RelativeLayout;
-
-/**
- * An abstraction over two implementations of the ActionBar - framework and appcompat.
- */
-public abstract class BridgeActionBar {
-    // Store a reference to the context so that we don't have to cast it repeatedly.
-    @NonNull protected final BridgeContext mBridgeContext;
-    @NonNull protected final SessionParams mParams;
-    // A Layout that contains the inflated action bar. The menu popup is added to this layout.
-    @Nullable protected final ViewGroup mEnclosingLayout;
-
-    private final View mDecorContent;
-    private final ActionBarCallback mCallback;
-
-    @SuppressWarnings("NullableProblems")  // Should be initialized by subclasses.
-    @NonNull private FrameLayout mContentRoot;
-
-    public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        mBridgeContext = context;
-        mParams = params;
-        mCallback = params.getLayoutlibCallback().getActionBarCallback();
-        ResourceValue layoutName = getLayoutResource(context);
-
-        int layoutId = 0;
-        if (layoutName == null) {
-            assert false : "Unable to find the layout for Action Bar.";
-        }
-        else {
-            if (layoutName.isFramework()) {
-                layoutId = context.getFrameworkResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-            } else {
-                layoutId = context.getProjectResourceValue(layoutName.getResourceType(),
-                        layoutName.getName(), 0);
-
-            }
-        }
-        if (layoutId == 0) {
-            assert false : String.format("Unable to resolve attribute \"%1$s\" of type \"%2$s\"",
-                    layoutName.getName(), layoutName.getResourceType());
-            mDecorContent = new MockView(context);
-            mEnclosingLayout = null;
-        }
-        else {
-            if (mCallback.isOverflowPopupNeeded()) {
-                // Create a RelativeLayout around the action bar, to which the overflow popup may be
-                // added.
-                mEnclosingLayout = new RelativeLayout(mBridgeContext);
-                setMatchParent(mEnclosingLayout);
-            } else {
-                mEnclosingLayout = null;
-            }
-
-            // Inflate action bar layout.
-            mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout,
-                    mEnclosingLayout != null);
-        }
-    }
-
-    /**
-     * Returns the Layout Resource that should be used to inflate the action bar. This layout
-     * should cover the complete screen, and have a FrameLayout included, where the content will
-     * be inflated.
-     */
-    protected abstract ResourceValue getLayoutResource(BridgeContext context);
-
-    protected LayoutInflater getInflater(BridgeContext context) {
-        return LayoutInflater.from(context);
-    }
-
-    protected void setContentRoot(@NonNull FrameLayout contentRoot) {
-        mContentRoot = contentRoot;
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    /**
-     * Returns the view inflated. This should contain both the ActionBar and the app content in it.
-     */
-    protected View getDecorContent() {
-        return mDecorContent;
-    }
-
-    /** Setup things like the title, subtitle, icon etc. */
-    protected void setupActionBar() {
-        setTitle();
-        setSutTitle();
-        setIcon();
-        setHomeAsUp(mCallback.getHomeButtonStyle() == HomeButtonStyle.SHOW_HOME_AS_UP);
-    }
-
-    protected abstract void setTitle(CharSequence title);
-    protected abstract void setSubtitle(CharSequence subtitle);
-    protected abstract void setIcon(String icon);
-    protected abstract void setHomeAsUp(boolean homeAsUp);
-
-    private void setTitle() {
-        RenderResources res = mBridgeContext.getRenderResources();
-
-        String title = mParams.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            setTitle(titleValue.getValue());
-        } else {
-            setTitle(title);
-        }
-    }
-
-    private void setSutTitle() {
-        String subTitle = mCallback.getSubTitle();
-        if (subTitle != null) {
-            setSubtitle(subTitle);
-        }
-    }
-
-    private void setIcon() {
-        String appIcon = mParams.getAppIcon();
-        if (appIcon != null) {
-            setIcon(appIcon);
-        }
-    }
-
-    public abstract void createMenuPopup();
-
-    /**
-     * The root view that represents the action bar and possibly the content included in it.
-     */
-    public View getRootView() {
-        return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout;
-    }
-
-    public ActionBarCallback getCallBack() {
-        return mCallback;
-    }
-
-    protected static void setMatchParent(View view) {
-        view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
deleted file mode 100644
index 7f8d992..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import android.os._Original_Build.VERSION_CODES;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static android.os._Original_Build.VERSION_CODES.*;
-
-/**
- * Various helper methods to simulate older versions of platform.
- */
-public class Config {
-
-    // each of these resource dirs must end in '/'
-    private static final String GINGERBREAD_DIR      = "/bars/v9/";
-    private static final String JELLYBEAN_DIR        = "/bars/v18/";
-    private static final String KITKAT_DIR           = "/bars/v19/";
-    private static final String DEFAULT_RESOURCE_DIR = "/bars/v21/";
-
-    private static final List<String> sDefaultResourceDir =
-            Collections.singletonList(DEFAULT_RESOURCE_DIR);
-
-    private static final int WHITE = 0xFFFFFFFF;
-    private static final int BLACK = 0xFF000000;
-
-    public static boolean showOnScreenNavBar(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, ICE_CREAM_SANDWICH);
-    }
-
-    public static int getStatusBarColor(int platformVersion) {
-        // return white for froyo and earlier; black otherwise.
-        return isGreaterOrEqual(platformVersion, GINGERBREAD) ? BLACK : WHITE;
-    }
-
-    public static List<String> getResourceDirs(int platformVersion) {
-        // Special case the most used scenario.
-        if (platformVersion == 0) {
-            return sDefaultResourceDir;
-        }
-        List<String> list = new ArrayList<String>(4);
-        // Gingerbread - uses custom battery and wifi icons.
-        if (platformVersion <= GINGERBREAD) {
-            list.add(GINGERBREAD_DIR);
-        }
-        // ICS - JellyBean uses custom battery, wifi.
-        if (platformVersion <= JELLY_BEAN_MR2) {
-            list.add(JELLYBEAN_DIR);
-        }
-        // KitKat - uses custom wifi and nav icons.
-        if (platformVersion <= KITKAT) {
-            list.add(KITKAT_DIR);
-        }
-        list.add(DEFAULT_RESOURCE_DIR);
-
-        return Collections.unmodifiableList(list);
-    }
-
-    public static String getTime(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, N)) {
-            return "7:00";
-        }
-        if (platformVersion < GINGERBREAD) {
-            return "2:20";
-        }
-        if (platformVersion < ICE_CREAM_SANDWICH) {
-            return "2:30";
-        }
-        if (platformVersion < JELLY_BEAN) {
-            return "4:00";
-        }
-        if (platformVersion < KITKAT) {
-            return "4:30";
-        }
-        if (platformVersion < LOLLIPOP) {
-            return "4:40";
-        }
-        if (platformVersion < LOLLIPOP_MR1) {
-            return "5:00";
-        }
-        if (platformVersion < M) {
-            return "5:10";
-        }
-        if (platformVersion < N) {
-            return "6:00";
-        }
-        // Should never happen.
-        return "4:04";
-    }
-
-    public static int getTimeColor(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, KITKAT) ||
-                platformVersion > FROYO && platformVersion < HONEYCOMB) {
-            // Gingerbread and KitKat onwards.
-            return WHITE;
-        }
-        // Black for froyo.
-        if (platformVersion < GINGERBREAD) {
-            return BLACK;
-        } else if (platformVersion < KITKAT) {
-            // Honeycomb to JB-mr2: Holo blue light.
-            return 0xff33b5e5;
-        }
-        // Should never happen.
-        return WHITE;
-    }
-
-    public static String getWifiIconType(int platformVersion) {
-        return isGreaterOrEqual(platformVersion, LOLLIPOP) ? "xml" : "png";
-    }
-
-    /**
-     * Compare simulated platform version and code from {@link VERSION_CODES} to check if
-     * the simulated platform is greater than or equal to the version code.
-     */
-    public static boolean isGreaterOrEqual(int platformVersion, int code) {
-        // simulated platform version = 0 means that we use the latest.
-        return platformVersion == 0 || platformVersion >= code;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
deleted file mode 100644
index 2984fc0..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-import com.android.resources.ResourceType;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import static android.os._Original_Build.VERSION_CODES.LOLLIPOP;
-
-/**
- * Base "bar" class for the window decor around the the edited layout.
- * This is basically an horizontal layout that loads a given layout on creation (it is read
- * through {@link Class#getResourceAsStream(String)}).
- *
- * The given layout should be a merge layout so that all the children belong to this class directly.
- *
- * It also provides a few utility methods to configure the content of the layout.
- */
-abstract class CustomBar extends LinearLayout {
-
-
-    private final int mSimulatedPlatformVersion;
-
-    protected abstract TextView getStyleableTextView();
-
-    protected CustomBar(BridgeContext context, int orientation, String layoutPath,
-            String name, int simulatedPlatformVersion) {
-        super(context);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-        setOrientation(orientation);
-        if (orientation == LinearLayout.HORIZONTAL) {
-            setGravity(Gravity.CENTER_VERTICAL);
-        } else {
-            setGravity(Gravity.CENTER_HORIZONTAL);
-        }
-
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-
-        XmlPullParser parser;
-        try {
-            parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name);
-
-            BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false);
-
-            try {
-                inflater.inflate(bridgeParser, this, true);
-            } finally {
-                bridgeParser.ensurePopped();
-            }
-        } catch (XmlPullParserException e) {
-            // Should not happen as the resource is bundled with the jar, and  ParserFactory should
-            // have been initialized.
-            assert false;
-        }
-    }
-
-    protected void loadIcon(int index, String iconName, Density density) {
-        loadIcon(index, iconName, density, false);
-    }
-
-    protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-
-            LayoutDirection dir = isRtl ? LayoutDirection.RTL : null;
-            IconLoader iconLoader = new IconLoader(iconName, density, mSimulatedPlatformVersion,
-                    dir);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                density = iconLoader.getDensity();
-                String path = iconLoader.getPath();
-                // look for a cached bitmap
-                Bitmap bitmap = Bridge.getCachedBitmap(path, Boolean.TRUE /*isFramework*/);
-                if (bitmap == null) {
-                    try {
-                        bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(path, bitmap, Boolean.TRUE /*isFramework*/);
-                    } catch (IOException e) {
-                        return;
-                    }
-                }
-
-                if (bitmap != null) {
-                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
-                            bitmap);
-                    imageView.setImageDrawable(drawable);
-                }
-            }
-        }
-    }
-
-    protected TextView setText(int index, String string, boolean reference) {
-        View child = getChildAt(index);
-        if (child instanceof TextView) {
-            TextView textView = (TextView) child;
-            setText(textView, string, reference);
-            return textView;
-        }
-
-        return null;
-    }
-
-    private void setText(TextView textView, String string, boolean reference) {
-        if (reference) {
-            ResourceValue value = getResourceValue(string);
-            if (value != null) {
-                string = value.getValue();
-            }
-        }
-        textView.setText(string);
-    }
-
-    protected void setStyle(String themeEntryName) {
-
-        BridgeContext bridgeContext = getContext();
-        RenderResources res = bridgeContext.getRenderResources();
-
-        ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/);
-        value = res.resolveResValue(value);
-
-        if (!(value instanceof StyleResourceValue)) {
-            return;
-        }
-
-        StyleResourceValue style = (StyleResourceValue) value;
-
-        // get the background
-        ResourceValue backgroundValue = res.findItemInStyle(style, "background",
-                true /*isFrameworkAttr*/);
-        backgroundValue = res.resolveResValue(backgroundValue);
-        if (backgroundValue != null) {
-            Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
-            if (d != null) {
-                setBackground(d);
-            }
-        }
-
-        TextView textView = getStyleableTextView();
-        if (textView != null) {
-            // get the text style
-            ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle",
-                    true /*isFrameworkAttr*/);
-            textStyleValue = res.resolveResValue(textStyleValue);
-            if (textStyleValue instanceof StyleResourceValue) {
-                StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
-
-                ResourceValue textSize = res.findItemInStyle(textStyle, "textSize",
-                        true /*isFrameworkAttr*/);
-                textSize = res.resolveResValue(textSize);
-
-                if (textSize != null) {
-                    TypedValue out = new TypedValue();
-                    if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
-                            true /*requireUnit*/)) {
-                        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                                out.getDimension(bridgeContext.getResources().getDisplayMetrics()));
-                    }
-                }
-
-
-                ResourceValue textColor = res.findItemInStyle(textStyle, "textColor",
-                        true);
-                textColor = res.resolveResValue(textColor);
-                if (textColor != null) {
-                    ColorStateList stateList = ResourceHelper.getColorStateList(
-                            textColor, bridgeContext);
-                    if (stateList != null) {
-                        textView.setTextColor(stateList);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public BridgeContext getContext() {
-        return (BridgeContext) mContext;
-    }
-
-    /**
-     * Find the background color for this bar from the theme attributes. Only relevant to StatusBar
-     * and NavigationBar.
-     * <p/>
-     * Returns 0 if not found.
-     *
-     * @param colorAttrName the attribute name for the background color
-     * @param translucentAttrName the attribute name for the translucency property of the bar.
-     *
-     * @throws NumberFormatException if color resolved to an invalid string.
-     */
-    protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) {
-        if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) {
-            return 0;
-        }
-        RenderResources renderResources = getContext().getRenderResources();
-        // First check if the bar is translucent.
-        boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources,
-                translucentAttrName, true, false);
-        if (translucent) {
-            // Keep in sync with R.color.system_bar_background_semi_transparent from system ui.
-            return 0x66000000;  // 40% black.
-        }
-        boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources,
-                "windowDrawsSystemBarBackgrounds", true, false);
-        if (transparent) {
-            return getColor(renderResources, colorAttrName);
-        }
-        return 0;
-    }
-
-    private static int getColor(RenderResources renderResources, String attr) {
-        // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue.
-        ResourceValue resource = renderResources.findItemInTheme(attr, true);
-        // Form @color/bar to the #AARRGGBB
-        resource = renderResources.resolveResValue(resource);
-        if (resource != null) {
-            ResourceType type = resource.getResourceType();
-            if (type == null || type == ResourceType.COLOR) {
-                // if no type is specified, the value may have been specified directly in the style
-                // file, rather than referencing a color resource value.
-                try {
-                    return ResourceHelper.getColor(resource.getValue());
-                } catch (NumberFormatException e) {
-                    // Conversion failed.
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Theme attribute @android:" + attr +
-                                    " does not reference a color, instead is '" +
-                                    resource.getValue() + "'.", resource);
-                }
-            }
-        }
-        return 0;
-    }
-
-    private ResourceValue getResourceValue(String reference) {
-        RenderResources res = getContext().getRenderResources();
-
-        // find the resource
-        ResourceValue value = res.findResValue(reference, false);
-
-        // resolve it if needed
-        return res.resolveResValue(value);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
deleted file mode 100644
index fd49c77..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.internal.R;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.InflateException;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ActionMenuPresenter;
-import android.widget.FrameLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-
-import java.util.ArrayList;
-
-/**
- * Creates the ActionBar as done by the framework.
- */
-public class FrameworkActionBar extends BridgeActionBar {
-
-    private static final String LAYOUT_ATTR_NAME = "windowActionBarFullscreenDecorLayout";
-
-    // The Action Bar
-    @NonNull private FrameworkActionBarWrapper mActionBar;
-
-    // A fake parent for measuring views.
-    @Nullable private ViewGroup mMeasureParent;
-
-    /**
-     * Inflate the action bar and attach it to {@code parentView}
-     */
-    public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
-        super(context, params);
-
-        View decorContent = getDecorContent();
-
-        mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(),
-                decorContent);
-
-        FrameLayout contentRoot = (FrameLayout) decorContent.findViewById(android.R.id.content);
-
-        // If something went wrong and we were not able to initialize the content root,
-        // just add a frame layout inside this and return.
-        if (contentRoot == null) {
-            contentRoot = new FrameLayout(context);
-            setMatchParent(contentRoot);
-            if (mEnclosingLayout != null) {
-                mEnclosingLayout.addView(contentRoot);
-            }
-            setContentRoot(contentRoot);
-        } else {
-            setContentRoot(contentRoot);
-            setupActionBar();
-            mActionBar.inflateMenus();
-        }
-    }
-
-    @Override
-    protected ResourceValue getLayoutResource(BridgeContext context) {
-        ResourceValue layoutName =
-                context.getRenderResources().findItemInTheme(LAYOUT_ATTR_NAME, true);
-        if (layoutName != null) {
-            // We may need to resolve the reference obtained.
-            layoutName = context.getRenderResources().findResValue(layoutName.getValue(),
-                    layoutName.isFramework());
-        }
-        if (layoutName == null) {
-             throw new InflateException("Unable to find action bar layout (" + LAYOUT_ATTR_NAME
-                    + ") in the current theme.");
-        }
-        return layoutName;
-    }
-
-    @Override
-    protected void setupActionBar() {
-        super.setupActionBar();
-        mActionBar.setupActionBar();
-    }
-
-    @Override
-    protected void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setHomeAsUp(homeAsUp);
-    }
-
-    @Override
-    protected void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    @Override
-    protected void setSubtitle(CharSequence subtitle) {
-        mActionBar.setSubTitle(subtitle);
-    }
-
-    @Override
-    protected void setIcon(String icon) {
-        mActionBar.setIcon(icon);
-    }
-
-    /**
-     * Creates a Popup and adds it to the content frame. It also adds another {@link FrameLayout} to
-     * the content frame which shall serve as the new content root.
-     */
-    @Override
-    public void createMenuPopup() {
-        if (!isOverflowPopupNeeded()) {
-            return;
-        }
-
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        MenuBuilder menu = mActionBar.getMenuBuilder();
-        OverflowMenuAdapter adapter = new OverflowMenuAdapter(menu, mActionBar.getPopupContext());
-
-        ListView listView = new ListView(mActionBar.getPopupContext(), null,
-                R.attr.dropDownListViewStyle);
-        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
-                measureContentWidth(adapter), LayoutParams.WRAP_CONTENT);
-        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_END);
-        if (mActionBar.isSplit()) {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-            layoutParams.bottomMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        } else {
-            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
-            layoutParams.topMargin = getActionBarHeight() + mActionBar.getMenuPopupMargin();
-        }
-        layoutParams.setMarginEnd(getPixelValue("5dp", metrics));
-        listView.setLayoutParams(layoutParams);
-        listView.setAdapter(adapter);
-        final TypedArray a = mActionBar.getPopupContext().obtainStyledAttributes(null,
-                R.styleable.PopupWindow, R.attr.popupMenuStyle, 0);
-        listView.setBackground(a.getDrawable(R.styleable.PopupWindow_popupBackground));
-        listView.setDivider(a.getDrawable(R.attr.actionBarDivider));
-        a.recycle();
-        listView.setElevation(mActionBar.getMenuPopupElevation());
-        assert mEnclosingLayout != null : "Unable to find view to attach ActionMenuPopup.";
-        mEnclosingLayout.addView(listView);
-    }
-
-    private boolean isOverflowPopupNeeded() {
-        boolean needed = mActionBar.isOverflowPopupNeeded();
-        if (!needed) {
-            return false;
-        }
-        // Copied from android.widget.ActionMenuPresenter.updateMenuView()
-        ArrayList<MenuItemImpl> menus = mActionBar.getMenuBuilder().getNonActionItems();
-        ActionMenuPresenter presenter = mActionBar.getActionMenuPresenter();
-        if (presenter == null) {
-            assert false : "Failed to create a Presenter for Action Bar Menus.";
-            return false;
-        }
-        if (presenter.isOverflowReserved() &&
-                menus != null) {
-            final int count = menus.size();
-            if (count == 1) {
-                needed = !menus.get(0).isActionViewExpanded();
-            } else {
-                needed = count > 0;
-            }
-        }
-        return needed;
-    }
-
-    // Copied from com.android.internal.view.menu.MenuPopHelper.measureContentWidth()
-    private int measureContentWidth(@NonNull ListAdapter adapter) {
-        // Menus don't tend to be long, so this is more sane than it looks.
-        int maxWidth = 0;
-        View itemView = null;
-        int itemType = 0;
-
-        Context context = mActionBar.getPopupContext();
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int count = adapter.getCount();
-        for (int i = 0; i < count; i++) {
-            final int positionType = adapter.getItemViewType(i);
-            if (positionType != itemType) {
-                itemType = positionType;
-                itemView = null;
-            }
-
-            if (mMeasureParent == null) {
-                mMeasureParent = new FrameLayout(context);
-            }
-
-            itemView = adapter.getView(i, itemView, mMeasureParent);
-            itemView.measure(widthMeasureSpec, heightMeasureSpec);
-
-            final int itemWidth = itemView.getMeasuredWidth();
-            int popupMaxWidth = Math.max(mBridgeContext.getMetrics().widthPixels / 2,
-                    context.getResources().getDimensionPixelSize(R.dimen.config_prefDialogWidth));
-            if (itemWidth >= popupMaxWidth) {
-                return popupMaxWidth;
-            } else if (itemWidth > maxWidth) {
-                maxWidth = itemWidth;
-            }
-        }
-
-        return maxWidth;
-    }
-
-    static int getPixelValue(@NonNull String value, @NonNull DisplayMetrics metrics) {
-        TypedValue typedValue = ResourceHelper.getValue(null, value, false /*requireUnit*/);
-        return (int) typedValue.getDimension(metrics);
-    }
-
-    // TODO: This is duplicated from RenderSessionImpl.
-    private int getActionBarHeight() {
-        RenderResources resources = mBridgeContext.getRenderResources();
-        DisplayMetrics metrics = mBridgeContext.getMetrics();
-        ResourceValue value = resources.findItemInTheme("actionBarSize", true);
-
-        // resolve it
-        value = resources.resolveResValue(value);
-
-        if (value != null) {
-            // get the numerical value, if available
-            TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
-                    true);
-            if (typedValue != null) {
-                // compute the pixel value based on the display metrics
-                return (int) typedValue.getDimension(metrics);
-
-            }
-        }
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
deleted file mode 100644
index 2cdc647..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.R;
-import com.android.internal.app.ToolbarActionBar;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.widget.ActionBarAccessor;
-import com.android.internal.widget.ActionBarView;
-import com.android.internal.widget.DecorToolbar;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.ResourceHelper;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowCallback;
-import android.widget.ActionMenuPresenter;
-import android.widget.ActionMenuView;
-import android.widget.Toolbar;
-import android.widget.Toolbar_Accessor;
-
-import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
-import static com.android.resources.ResourceType.MENU;
-
-/**
- * A common API to access {@link ToolbarActionBar} and {@link WindowDecorActionBar}.
- */
-public abstract class FrameworkActionBarWrapper {
-
-    @NonNull protected ActionBar mActionBar;
-    @NonNull protected ActionBarCallback mCallback;
-    @NonNull protected BridgeContext mContext;
-
-    /**
-     * Returns a wrapper around different implementations of the Action Bar to provide a common API.
-     *
-     * @param decorContent the top level view returned by inflating
-     *                     ?attr/windowActionBarFullscreenDecorLayout
-     */
-    @NonNull
-    public static FrameworkActionBarWrapper getActionBarWrapper(@NonNull BridgeContext context,
-            @NonNull ActionBarCallback callback, @NonNull View decorContent) {
-        View view = decorContent.findViewById(R.id.action_bar);
-        if (view instanceof Toolbar) {
-            return new ToolbarWrapper(context, callback, (Toolbar) view);
-        } else if (view instanceof ActionBarView) {
-            return new WindowActionBarWrapper(context, callback, decorContent,
-                    (ActionBarView) view);
-        } else {
-            throw new IllegalStateException("Can't make an action bar out of " +
-                    view.getClass().getSimpleName());
-        }
-    }
-
-    FrameworkActionBarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-            @NonNull ActionBar actionBar) {
-        mActionBar = actionBar;
-        mCallback = callback;
-        mContext = context;
-    }
-
-    /** A call to setup any custom properties. */
-    protected void setupActionBar() {
-        // Nothing to do here.
-    }
-
-    public void setTitle(CharSequence title) {
-        mActionBar.setTitle(title);
-    }
-
-    public void setSubTitle(CharSequence subTitle) {
-        if (subTitle != null) {
-            mActionBar.setSubtitle(subTitle);
-        }
-    }
-
-    public void setHomeAsUp(boolean homeAsUp) {
-        mActionBar.setDisplayHomeAsUpEnabled(homeAsUp);
-    }
-
-    public void setIcon(String icon) {
-        // Nothing to do.
-    }
-
-    protected boolean isSplit() {
-        return getDecorToolbar().isSplit();
-    }
-
-    protected boolean isOverflowPopupNeeded() {
-        return mCallback.isOverflowPopupNeeded();
-    }
-
-    /**
-     * Gets the menus to add to the action bar from the callback, resolves them, inflates them and
-     * adds them to the action bar.
-     */
-    protected void inflateMenus() {
-        MenuInflater inflater = new MenuInflater(getActionMenuContext());
-        MenuBuilder menuBuilder = getMenuBuilder();
-        for (String name : mCallback.getMenuIdNames()) {
-            int id;
-            if (name.startsWith(ANDROID_NS_NAME_PREFIX)) {
-                // Framework menu.
-                name = name.substring(ANDROID_NS_NAME_PREFIX.length());
-                id = mContext.getFrameworkResourceValue(MENU, name, -1);
-            } else {
-                // Project menu.
-                id = mContext.getProjectResourceValue(MENU, name, -1);
-            }
-            if (id > -1) {
-                inflater.inflate(id, menuBuilder);
-            }
-        }
-    }
-
-    /**
-     * The context used for the ActionBar and the menus in the ActionBarView.
-     */
-    @NonNull
-    protected Context getActionMenuContext() {
-        return mActionBar.getThemedContext();
-    }
-
-    /**
-     * The context used to inflate the popup menu.
-     */
-    @NonNull
-    abstract Context getPopupContext();
-
-    /**
-     * The Menu in which to inflate the user's menus.
-     */
-    @NonNull
-    abstract MenuBuilder getMenuBuilder();
-
-    @Nullable
-    abstract ActionMenuPresenter getActionMenuPresenter();
-
-    /**
-     * Framework's wrapper over two ActionBar implementations.
-     */
-    @NonNull
-    abstract DecorToolbar getDecorToolbar();
-
-    abstract int getMenuPopupElevation();
-
-    /**
-     * Margin between the menu popup and the action bar.
-     */
-    abstract int getMenuPopupMargin();
-
-    // ---- The implementations ----
-
-    /**
-     * Material theme uses {@link Toolbar} as the action bar. This wrapper provides access to
-     * Toolbar using a common API.
-     */
-    private static class ToolbarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull
-        private final Toolbar mToolbar;  // This is the view.
-
-        ToolbarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback,
-                @NonNull Toolbar toolbar) {
-            super(context, callback, new ToolbarActionBar(toolbar, "", new WindowCallback()));
-            mToolbar = toolbar;
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // Inflating the menus isn't enough. ActionMenuPresenter needs to be initialized too.
-            MenuBuilder menu = getMenuBuilder();
-            DecorToolbar decorToolbar = getDecorToolbar();
-            // Setting a menu different from the above initializes the presenter.
-            decorToolbar.setMenu(new MenuBuilder(getActionMenuContext()), null);
-            // ActionMenuView needs to be recreated to be able to set the menu back.
-            ActionMenuPresenter presenter = getActionMenuPresenter();
-            if (presenter != null) {
-                presenter.setMenuView(new ActionMenuView(getPopupContext()));
-            }
-            decorToolbar.setMenu(menu, null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return Toolbar_Accessor.getPopupContext(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            return (MenuBuilder) mToolbar.getMenu();
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return Toolbar_Accessor.getActionMenuPresenter(mToolbar);
-        }
-
-        @NonNull
-        @Override
-        DecorToolbar getDecorToolbar() {
-            return mToolbar.getWrapper();
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 10;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return 0;
-        }
-    }
-
-    /**
-     * Holo theme uses {@link WindowDecorActionBar} as the action bar. This wrapper provides
-     * access to it using a common API.
-     */
-    private static class WindowActionBarWrapper extends FrameworkActionBarWrapper {
-
-        @NonNull private final WindowDecorActionBar mActionBar;
-        @NonNull private final ActionBarView mActionBarView;
-        @NonNull private final View mDecorContentRoot;
-        private MenuBuilder mMenuBuilder;
-
-        public WindowActionBarWrapper(@NonNull BridgeContext context,
-                @NonNull ActionBarCallback callback, @NonNull View decorContentRoot,
-                @NonNull ActionBarView actionBarView) {
-            super(context, callback, new WindowDecorActionBar(decorContentRoot));
-            mActionBarView = actionBarView;
-            mActionBar = (WindowDecorActionBar) super.mActionBar;
-            mDecorContentRoot = decorContentRoot;
-        }
-
-        @Override
-        protected void setupActionBar() {
-
-            // Set the navigation mode.
-            int navMode = mCallback.getNavigationMode();
-            mActionBar.setNavigationMode(navMode);
-            //noinspection deprecation
-            if (navMode == ActionBar.NAVIGATION_MODE_TABS) {
-                setupTabs(3);
-            }
-
-            // Set action bar to be split, if needed.
-            ViewGroup splitView = (ViewGroup) mDecorContentRoot.findViewById(R.id.split_action_bar);
-            if (splitView != null) {
-                mActionBarView.setSplitView(splitView);
-                Resources res = mContext.getResources();
-                boolean split = res.getBoolean(R.bool.split_action_bar_is_narrow)
-                        && mCallback.getSplitActionBarWhenNarrow();
-                mActionBarView.setSplitToolbar(split);
-            }
-        }
-
-        @Override
-        public void setIcon(String icon) {
-            // Set the icon only if the action bar doesn't specify an icon.
-            if (!mActionBar.hasIcon() && icon != null) {
-                Drawable iconDrawable = getDrawable(icon, false);
-                if (iconDrawable != null) {
-                    mActionBar.setIcon(iconDrawable);
-                }
-            }
-        }
-
-        @Override
-        protected void inflateMenus() {
-            super.inflateMenus();
-            // The super implementation doesn't set the menu on the view. Set it here.
-            mActionBarView.setMenu(getMenuBuilder(), null);
-        }
-
-        @NonNull
-        @Override
-        Context getPopupContext() {
-            return getActionMenuContext();
-        }
-
-        @NonNull
-        @Override
-        MenuBuilder getMenuBuilder() {
-            if (mMenuBuilder == null) {
-                mMenuBuilder = new MenuBuilder(getActionMenuContext());
-            }
-            return mMenuBuilder;
-        }
-
-        @Nullable
-        @Override
-        ActionMenuPresenter getActionMenuPresenter() {
-            return ActionBarAccessor.getActionMenuPresenter(mActionBarView);
-        }
-
-        @NonNull
-        @Override
-        ActionBarView getDecorToolbar() {
-            return mActionBarView;
-        }
-
-        @Override
-        int getMenuPopupElevation() {
-            return 0;
-        }
-
-        @Override
-        int getMenuPopupMargin() {
-            return -FrameworkActionBar.getPixelValue("10dp", mContext.getMetrics());
-        }
-
-        // TODO: Use an adapter, like List View to set up tabs.
-        @SuppressWarnings("deprecation")  // For Tab
-        private void setupTabs(int num) {
-            for (int i = 1; i <= num; i++) {
-                Tab tab = mActionBar.newTab().setText("Tab" + i).setTabListener(new TabListener() {
-                    @Override
-                    public void onTabUnselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabSelected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                    @Override
-                    public void onTabReselected(Tab t, FragmentTransaction ft) {
-                        // pass
-                    }
-                });
-                mActionBar.addTab(tab);
-            }
-        }
-
-        @Nullable
-        private Drawable getDrawable(@NonNull String name, boolean isFramework) {
-            RenderResources res = mContext.getRenderResources();
-            ResourceValue value = res.findResValue(name, isFramework);
-            value = res.resolveResValue(value);
-            if (value != null) {
-                return ResourceHelper.getDrawable(value, mContext);
-            }
-            return null;
-        }
-
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
deleted file mode 100644
index 9ab2e82..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/IconLoader.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.resources.Density;
-import com.android.resources.LayoutDirection;
-
-import java.io.InputStream;
-
-public class IconLoader {
-
-    private final String mIconName;
-    private final Density mDesiredDensity;
-    private final int mPlatformVersion;
-    private final LayoutDirection mDirection;
-
-    private Density mCurrentDensity;
-    private StringBuilder mCurrentPath;
-
-    IconLoader(String iconName, Density density, int platformVersion, LayoutDirection direction) {
-        mIconName = iconName;
-        mDesiredDensity = density;
-        mPlatformVersion = platformVersion;
-        mDirection = direction;
-        // An upper bound on the length of the path for the icon: /bars/v21/ldrtl-xxxhdpi/
-        final int iconPathLength = 24;
-        mCurrentPath = new StringBuilder(iconPathLength + iconName.length());
-    }
-
-    public InputStream getIcon() {
-        for (String resourceDir : Config.getResourceDirs(mPlatformVersion)) {
-            mCurrentDensity = null;
-            InputStream stream = getIcon(resourceDir);
-            if (stream != null) {
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the density of the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public Density getDensity() {
-        return mCurrentDensity;
-    }
-
-    /**
-     * Should only be called after {@link #getIcon()}. Returns the path to the icon, if found by
-     * {@code getIcon()}. If no icon was found, then the return value has no meaning.
-     */
-    public String getPath() {
-        return mCurrentPath.toString();
-    }
-
-    /**
-     * Search for icon in the resource directory. This iterates over all densities.
-     * If a match is found, mCurrentDensity will be set to the icon's density.
-     */
-    private InputStream getIcon(String resourceDir) {
-        // First check for the desired density.
-        InputStream stream = getIcon(resourceDir, mDesiredDensity);
-        if (stream != null) {
-            mCurrentDensity = mDesiredDensity;
-            return stream;
-        }
-        // Didn't find in the desired density. Search in all.
-        for (Density density : Density.values()) {
-            if (density == mDesiredDensity) {
-                // Skip the desired density since it's already been checked.
-                continue;
-            }
-            stream = getIcon(resourceDir, density);
-            if (stream != null) {
-                mCurrentDensity = density;
-                return stream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the icon for given density present in the given resource directory, taking layout
-     * direction into consideration.
-     */
-    private InputStream getIcon(String resourceDir, Density density) {
-        mCurrentPath.setLength(0);
-        // Currently we don't have any LTR only resources and hence the check is skipped. If they
-        // are ever added, change to:
-        // if (mDirection == LayoutDirection.RTL || mDirection == LayoutDirection.LTR) {
-        if (mDirection == LayoutDirection.RTL) {
-            mCurrentPath.append(resourceDir)
-                    .append(mDirection.getResourceValue())
-                    .append('-')
-                    .append(density.getResourceValue())
-                    .append('/')
-                    .append(mIconName);
-            InputStream stream = getClass().getResourceAsStream(mCurrentPath.toString());
-            if (stream != null) {
-                return stream;
-            }
-            mCurrentPath.setLength(0);
-        }
-        mCurrentPath.append(resourceDir)
-                .append(density.getResourceValue())
-                .append('/')
-                .append(mIconName);
-        return getClass().getResourceAsStream(mCurrentPath.toString());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
deleted file mode 100644
index dfbc69b..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.util.DisplayMetrics;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class NavigationBar extends CustomBar {
-
-    /** Navigation bar background color attribute name. */
-    private static final String ATTR_COLOR = "navigationBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation";
-    // These correspond to @dimen/navigation_side_padding in the system ui code.
-    private static final int PADDING_WIDTH_DEFAULT = 36;
-    private static final int PADDING_WIDTH_SW360 = 40;
-    private static final int PADDING_WIDTH_SW400 = 50;
-    // These corresponds to @dimen/navigation_key_width in the system ui code.
-    private static final int WIDTH_DEFAULT = 36;
-    private static final int WIDTH_SW360 = 40;
-    private static final int WIDTH_SW600 = 48;
-    protected static final String LAYOUT_XML = "/bars/navigation_bar.xml";
-    private static final String LAYOUT_600DP_XML = "/bars/navigation_bar600dp.xml";
-
-    public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion) {
-        this(context, density, orientation, isRtl, rtlEnabled, simulatedPlatformVersion,
-          getShortestWidth(context)>= 600 ? LAYOUT_600DP_XML : LAYOUT_XML);
-    }
-
-    protected NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
-      boolean rtlEnabled, int simulatedPlatformVersion, String layoutPath) {
-        super(context, orientation, layoutPath, "navigation_bar.xml", simulatedPlatformVersion);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? 0xFF000000 : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is a spacer.
-        int back = 1;
-        int recent = 5;
-        if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
-            // If RTL is enabled, then layoutlib mirrors the layout for us.
-            back = 5;
-            recent = 1;
-        }
-
-        //noinspection SpellCheckingInspection
-        loadIcon(back, "ic_sysbar_back.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(3, "ic_sysbar_home.png", density, isRtl);
-        //noinspection SpellCheckingInspection
-        loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
-        setupNavBar(context, orientation);
-    }
-
-    private void setupNavBar(BridgeContext context, int orientation) {
-        float sw = getShortestWidth(context);
-        View leftPadding = getChildAt(0);
-        View rightPadding = getChildAt(6);
-        setSize(context, leftPadding, orientation, getSidePadding(sw));
-        setSize(context, rightPadding, orientation, getSidePadding(sw));
-        int navButtonWidth = getWidth(sw);
-        for (int i = 1; i < 6; i += 2) {
-            View navButton = getChildAt(i);
-            setSize(context, navButton, orientation, navButtonWidth);
-        }
-        if (sw >= 600) {
-            setSize(context, getChildAt(2), orientation, 128);
-            setSize(context, getChildAt(4), orientation, 128);
-        }
-    }
-
-    private static void setSize(BridgeContext context, View view, int orientation, int size) {
-        size *= context.getMetrics().density;
-        LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
-        if (orientation == HORIZONTAL) {
-            layoutParams.width = size;
-        } else {
-            layoutParams.height = size;
-        }
-        view.setLayoutParams(layoutParams);
-    }
-
-    protected int getSidePadding(float sw) {
-        if (sw >= 400) {
-            return PADDING_WIDTH_SW400;
-        }
-        if (sw >= 360) {
-            return PADDING_WIDTH_SW360;
-        }
-        return PADDING_WIDTH_DEFAULT;
-    }
-
-    private static int getWidth(float sw) {
-        if (sw >= 600) {
-            return WIDTH_SW600;
-        }
-        if (sw >= 360) {
-            return WIDTH_SW360;
-        }
-        return WIDTH_DEFAULT;
-    }
-
-    private static float getShortestWidth(BridgeContext context) {
-        DisplayMetrics metrics = context.getMetrics();
-        float sw = metrics.widthPixels < metrics.heightPixels ?
-                metrics.widthPixels : metrics.heightPixels;
-        sw /= metrics.density;
-        return sw;
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
deleted file mode 100644
index 778305d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/OverflowMenuAdapter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-
-import java.util.ArrayList;
-
-/**
- * Provides an adapter for Overflow menu popup. This is very similar to
- * {@code MenuPopupHelper.MenuAdapter}
- */
-public class OverflowMenuAdapter extends BaseAdapter {
-
-    private final MenuBuilder mMenu;
-    private int mExpandedIndex = -1;
-    private final Context context;
-
-    public OverflowMenuAdapter(MenuBuilder menu, Context context) {
-        mMenu = menu;
-        findExpandedIndex();
-        this.context = context;
-    }
-
-    @Override
-    public int getCount() {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex < 0) {
-            return items.size();
-        }
-        return items.size() - 1;
-    }
-
-    @Override
-    public MenuItemImpl getItem(int position) {
-        ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-        if (mExpandedIndex >= 0 && position >= mExpandedIndex) {
-            position++;
-        }
-        return items.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        // Since a menu item's ID is optional, we'll use the position as an
-        // ID for the item in the AdapterView
-        return position;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        if (convertView == null) {
-            LayoutInflater mInflater = LayoutInflater.from(context);
-            convertView = mInflater.inflate(com.android.internal.R.layout.popup_menu_item_layout,
-                    parent, false);
-        }
-
-        MenuView.ItemView itemView = (MenuView.ItemView) convertView;
-        itemView.initialize(getItem(position), 0);
-        return convertView;
-    }
-
-    private void findExpandedIndex() {
-        final MenuItemImpl expandedItem = mMenu.getExpandedItem();
-        if (expandedItem != null) {
-            final ArrayList<MenuItemImpl> items = mMenu.getNonActionItems();
-            final int count = items.size();
-            for (int i = 0; i < count; i++) {
-                final MenuItemImpl item = items.get(i);
-                if (item == expandedItem) {
-                    mExpandedIndex = i;
-                    return;
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
deleted file mode 100644
index 2dc7c65..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class StatusBar extends CustomBar {
-
-    private final int mSimulatedPlatformVersion;
-    /** Status bar background color attribute name. */
-    private static final String ATTR_COLOR = "statusBarColor";
-    /** Attribute for translucency property. */
-    public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus";
-
-    /**
-     * Constructor to be used when creating the {@link StatusBar} as a regular control. This
-     * is currently used by the theme editor.
-     */
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(Context context, AttributeSet attrs) {
-        this((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                context.getApplicationInfo().targetSdkVersion);
-    }
-
-    @SuppressWarnings("UnusedParameters")
-    public StatusBar(BridgeContext context, Density density, boolean isRtl, boolean rtlEnabled,
-            int simulatedPlatformVersion) {
-        // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-        super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml",
-                simulatedPlatformVersion);
-        mSimulatedPlatformVersion = simulatedPlatformVersion;
-
-        // FIXME: use FILL_H?
-        setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT);
-
-        int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT);
-        setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        // 0 is the spacer
-        loadIcon(1, "stat_sys_wifi_signal_4_fully."
-                        + Config.getWifiIconType(simulatedPlatformVersion), density);
-        loadIcon(2, "stat_sys_battery_100.png", density);
-        setText(3, Config.getTime(simulatedPlatformVersion), false)
-                .setTextColor(Config.getTimeColor(simulatedPlatformVersion));
-    }
-
-    @Override
-    protected void loadIcon(int index, String iconName, Density density) {
-        if (!iconName.endsWith(".xml")) {
-            super.loadIcon(index, iconName, density);
-            return;
-        }
-        View child = getChildAt(index);
-        if (child instanceof ImageView) {
-            ImageView imageView = (ImageView) child;
-            // The xml is stored only in xhdpi.
-            IconLoader iconLoader = new IconLoader(iconName, Density.XHIGH,
-                    mSimulatedPlatformVersion, null);
-            InputStream stream = iconLoader.getIcon();
-
-            if (stream != null) {
-                try {
-                    BridgeXmlBlockParser parser = new BridgeXmlBlockParser(
-                            ParserFactory.create(stream, null), (BridgeContext) mContext, true);
-                    imageView.setImageDrawable(
-                            Drawable.createFromXml(mContext.getResources(), parser));
-                } catch (XmlPullParserException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                } catch (IOException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
-                            null);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
deleted file mode 100644
index 0435280..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * Navigation Bar for the Theme Editor preview.
- *
- * For small bars, it is identical to {@link NavigationBar}.
- * But wide bars from {@link NavigationBar} are too wide for the Theme Editor preview.
- * To solve that problem, {@link ThemePreviewNavigationBar} use the layout for small bars,
- * and have no padding on the sides. That way, they have a similar look as the true ones,
- * and they fit in the Theme Editor preview.
- */
-public class ThemePreviewNavigationBar extends NavigationBar {
-    private static final int PADDING_WIDTH_SW600 = 0;
-
-    @SuppressWarnings("unused")
-    public ThemePreviewNavigationBar(Context context, AttributeSet attrs) {
-        super((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                0, LAYOUT_XML);
-    }
-
-    @Override
-    protected int getSidePadding(float sw) {
-        if (sw >= 600) {
-            return PADDING_WIDTH_SW600;
-        }
-        return super.getSidePadding(sw);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
deleted file mode 100644
index 4fe1001..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class TitleBar extends CustomBar {
-
-    private TextView mTextView;
-
-    public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) {
-        super(context, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml",
-                simulatedPlatformVersion);
-
-        // Cannot access the inside items through id because no R.id values have been
-        // created for them.
-        // We do know the order though.
-        mTextView = setText(0, label, true);
-
-        setStyle("windowTitleBackgroundStyle");
-    }
-
-    @Override
-    protected TextView getStyleableTextView() {
-        return mTextView;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
deleted file mode 100644
index 11da445..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.layoutlib.bridge.util.Debug;
-import com.android.layoutlib.bridge.util.SparseWeakArray;
-
-import android.annotation.Nullable;
-import android.util.SparseArray;
-
-import java.io.PrintStream;
-import java.lang.ref.WeakReference;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Manages native delegates.
- *
- * This is used in conjunction with layoublib_create: certain Android java classes are mere
- * wrappers around a heavily native based implementation, and we need a way to run these classes
- * in our Android Studio rendering framework without bringing all the native code from the Android
- * platform.
- *
- * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their
- * native methods by "delegate calls".
- *
- * For example, a native method android.graphics.Matrix.init(...) will actually become
- * a call to android.graphics.Matrix_Delegate.init(...).
- *
- * The Android java classes that use native code uses an int (Java side) to reference native
- * objects. This int is generally directly the pointer to the C structure counterpart.
- * Typically a creation method will return such an int, and then this int will be passed later
- * to a Java method to identify the C object to manipulate.
- *
- * Since we cannot use the Java object reference as the int directly, DelegateManager manages the
- * int -> Delegate class link.
- *
- * Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(long)} to get the Java object matching the int.
- *
- * Typical native init methods are returning a new int back to the Java class, so
- * {@link #addNewDelegate(Object)} does the same.
- *
- * The JNI references are counted, so we do the same through a {@link WeakReference}. Because
- * the Java object needs to count as a reference (even though it only holds an int), we use the
- * following mechanism:
- *
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes
- *   the delegate to/from a set. This set holds the reference and prevents the GC from reclaiming
- *   the delegate.
- *
- * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a
- *   {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically
- *   when nothing references it. This means that any class that holds a delegate (except for the
- *   Java main class) must not use the int but the Delegate class instead. The integers must
- *   only be used in the API between the main Java class and the Delegate.
- *
- * @param <T> the delegate class to manage
- */
-public final class DelegateManager<T> {
-    @SuppressWarnings("FieldCanBeLocal")
-    private final Class<T> mClass;
-    private static final SparseWeakArray<Object> sDelegates = new SparseWeakArray<>();
-    /** Set used to store delegates when their main object holds a reference to them.
-     * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
-     * @see #addNewDelegate(Object)
-     * @see #removeJavaReferenceFor(long)
-     */
-    private static final Set<Object> sJavaReferences = new HashSet<>();
-    private static final AtomicLong sDelegateCounter = new AtomicLong(1);
-
-    public DelegateManager(Class<T> theClass) {
-        mClass = theClass;
-    }
-
-    /**
-     * Returns the delegate from the given native int.
-     * <p>
-     * If the int is zero, then this will always return null.
-     * <p>
-     * If the int is non zero and the delegate is not found, this will throw an assert.
-     *
-     * @param native_object the native int.
-     * @return the delegate or null if not found.
-     */
-    @Nullable
-    public T getDelegate(long native_object) {
-        if (native_object > 0) {
-            Object delegate;
-            synchronized (DelegateManager.class) {
-                delegate = sDelegates.get(native_object);
-            }
-
-            if (Debug.DEBUG) {
-                if (delegate == null) {
-                    System.err.println("Unknown " + mClass.getSimpleName() + " with int " +
-                            native_object);
-                }
-            }
-
-            assert delegate != null;
-            //noinspection unchecked
-            return (T)delegate;
-        }
-        return null;
-    }
-
-    /**
-     * Adds a delegate to the manager and returns the native int used to identify it.
-     * @param newDelegate the delegate to add
-     * @return a unique native int to identify the delegate
-     */
-    public long addNewDelegate(T newDelegate) {
-        long native_object = sDelegateCounter.getAndIncrement();
-        synchronized (DelegateManager.class) {
-            sDelegates.put(native_object, newDelegate);
-            // Only for development: assert !sJavaReferences.contains(newDelegate);
-            sJavaReferences.add(newDelegate);
-        }
-
-        if (Debug.DEBUG) {
-            System.out.println(
-                    "New " + mClass.getSimpleName() + " " +
-                            "with int " +
-                            native_object);
-        }
-
-        return native_object;
-    }
-
-    /**
-     * Removes the main reference on the given delegate.
-     * @param native_object the native integer representing the delegate.
-     */
-    public void removeJavaReferenceFor(long native_object) {
-        synchronized (DelegateManager.class) {
-            T delegate = getDelegate(native_object);
-
-            if (Debug.DEBUG) {
-                System.out.println("Removing main Java ref on " + mClass.getSimpleName() +
-                        " with int " + native_object);
-            }
-
-            sJavaReferences.remove(delegate);
-        }
-    }
-
-    public synchronized static void dump(PrintStream out) {
-        for (Object reference : sJavaReferences) {
-            int idx = sDelegates.indexOfValue(reference);
-            out.printf("[%d] %s\n", sDelegates.keyAt(idx), reference.getClass().getSimpleName());
-        }
-        out.printf("\nTotal number of objects: %d\n", sJavaReferences.size());
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
deleted file mode 100644
index 7526e09..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter_Delegate;
-import android.graphics.Paint;
-import android.graphics.Paint_Delegate;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Region_Delegate;
-import android.graphics.Shader_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-
-/**
- * Class representing a graphics context snapshot, as well as a context stack as a linked list.
- * <p>
- * This is based on top of {@link Graphics2D} but can operate independently if none are available
- * yet when setting transforms and clip information.
- * <p>
- * This allows for drawing through {@link #draw(Drawable, Paint_Delegate, boolean, boolean)} and
- * {@link #draw(Drawable)}
- *
- * Handling of layers (created with {@link Canvas#saveLayer(RectF, Paint, int)}) is handled through
- * a list of Graphics2D for each layers. The class actually maintains a list of {@link Layer}
- * for each layer. Doing a save() will duplicate this list so that each graphics2D object
- * ({@link Layer#getGraphics()}) is configured only for the new snapshot.
- */
-public class GcSnapshot {
-
-    private final GcSnapshot mPrevious;
-    private final int mFlags;
-
-    /** list of layers. The first item in the list is always the  */
-    private final ArrayList<Layer> mLayers = new ArrayList<Layer>();
-
-    /** temp transform in case transformation are set before a Graphics2D exists */
-    private AffineTransform mTransform = null;
-    /** temp clip in case clipping is set before a Graphics2D exists */
-    private Area mClip = null;
-
-    // local layer data
-    /** a local layer created with {@link Canvas#saveLayer(RectF, Paint, int)}.
-     * If this is null, this does not mean there's no layer, just that the snapshot is not the
-     * one that created the layer.
-     * @see #getLayerSnapshot()
-     */
-    private final Layer mLocalLayer;
-    private final Paint_Delegate mLocalLayerPaint;
-    private final Rect mLayerBounds;
-
-    public interface Drawable {
-        void draw(Graphics2D graphics, Paint_Delegate paint);
-    }
-
-    /**
-     * Class containing information about a layer.
-     *
-     * This contains graphics, bitmap and layer information.
-     */
-    private static class Layer {
-        private final Graphics2D mGraphics;
-        private final Bitmap_Delegate mBitmap;
-        private final BufferedImage mImage;
-        /** the flags that were used to configure the layer. This is never changed, and passed
-         * as is when {@link #makeCopy()} is called */
-        private final int mFlags;
-        /** the original content of the layer when the next object was created. This is not
-         * passed in {@link #makeCopy()} and instead is recreated when a new layer is added
-         * (depending on its flags) */
-        private BufferedImage mOriginalCopy;
-
-        /**
-         * Creates a layer with a graphics and a bitmap. This is only used to create
-         * the base layer.
-         *
-         * @param graphics the graphics
-         * @param bitmap the bitmap
-         */
-        Layer(Graphics2D graphics, Bitmap_Delegate bitmap) {
-            mGraphics = graphics;
-            mBitmap = bitmap;
-            mImage = mBitmap.getImage();
-            mFlags = 0;
-        }
-
-        /**
-         * Creates a layer with a graphics and an image. If the image belongs to a
-         * {@link Bitmap_Delegate} (case of the base layer), then
-         * {@link Layer#Layer(Graphics2D, Bitmap_Delegate)} should be used.
-         *
-         * @param graphics the graphics the new graphics for this layer
-         * @param image the image the image from which the graphics came
-         * @param flags the flags that were used to save this layer
-         */
-        Layer(Graphics2D graphics, BufferedImage image, int flags) {
-            mGraphics = graphics;
-            mBitmap = null;
-            mImage = image;
-            mFlags = flags;
-        }
-
-        /** The Graphics2D, guaranteed to be non null */
-        Graphics2D getGraphics() {
-            return mGraphics;
-        }
-
-        /** The BufferedImage, guaranteed to be non null */
-        BufferedImage getImage() {
-            return mImage;
-        }
-
-        /** Returns the layer save flags. This is only valid for additional layers.
-         * For the base layer this will always return 0;
-         * For a given layer, all further copies of this {@link Layer} object in new snapshots
-         * will always return the same value.
-         */
-        int getFlags() {
-            return mFlags;
-        }
-
-        Layer makeCopy() {
-            if (mBitmap != null) {
-                return new Layer((Graphics2D) mGraphics.create(), mBitmap);
-            }
-
-            return new Layer((Graphics2D) mGraphics.create(), mImage, mFlags);
-        }
-
-        /** sets an optional copy of the original content to be used during restore */
-        void setOriginalCopy(BufferedImage image) {
-            mOriginalCopy = image;
-        }
-
-        BufferedImage getOriginalCopy() {
-            return mOriginalCopy;
-        }
-
-        void change() {
-            if (mBitmap != null) {
-                mBitmap.change();
-            }
-        }
-
-        /**
-         * Sets the clip for the graphics2D object associated with the layer.
-         * This should be used over the normal Graphics2D setClip method.
-         *
-         * @param clipShape the shape to use a the clip shape.
-         */
-        void setClip(Shape clipShape) {
-            // because setClip is only guaranteed to work with rectangle shape,
-            // first reset the clip to max and then intersect the current (empty)
-            // clip with the shap.
-            mGraphics.setClip(null);
-            mGraphics.clip(clipShape);
-        }
-
-        /**
-         * Clips the layer with the given shape. This performs an intersect between the current
-         * clip shape and the given shape.
-         * @param shape the new clip shape.
-         */
-        public void clip(Shape shape) {
-            mGraphics.clip(shape);
-        }
-    }
-
-    /**
-     * Creates the root snapshot associating it with a given bitmap.
-     * <p>
-     * If <var>bitmap</var> is null, then {@link GcSnapshot#setBitmap(Bitmap_Delegate)} must be
-     * called before the snapshot can be used to draw. Transform and clip operations are permitted
-     * before.
-     *
-     * @param bitmap the image to associate to the snapshot or null.
-     * @return the root snapshot
-     */
-    public static GcSnapshot createDefaultSnapshot(Bitmap_Delegate bitmap) {
-        GcSnapshot snapshot = new GcSnapshot();
-        if (bitmap != null) {
-            snapshot.setBitmap(bitmap);
-        }
-
-        return snapshot;
-    }
-
-    /**
-     * Saves the current state according to the given flags and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#save(int)}
-     *
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#save(int)
-     */
-    public GcSnapshot save(int flags) {
-        return new GcSnapshot(this, null /*layerbounds*/, null /*paint*/, flags);
-    }
-
-    /**
-     * Saves the current state and creates a new layer, and returns the new current snapshot.
-     * <p/>
-     * This is the equivalent of {@link Canvas#saveLayer(RectF, Paint, int)}
-     *
-     * @param layerBounds the layer bounds
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the save flags.
-     * @return the new snapshot
-     *
-     * @see Canvas#saveLayer(RectF, Paint, int)
-     */
-    public GcSnapshot saveLayer(RectF layerBounds, Paint_Delegate paint, int flags) {
-        return new GcSnapshot(this, layerBounds, paint, flags);
-    }
-
-    /**
-     * Creates the root snapshot.
-     * {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
-     */
-    private GcSnapshot() {
-        mPrevious = null;
-        mFlags = 0;
-        mLocalLayer = null;
-        mLocalLayerPaint = null;
-        mLayerBounds = null;
-    }
-
-    /**
-     * Creates a new {@link GcSnapshot} on top of another one, with a layer data to be restored
-     * into the main graphics when {@link #restore()} is called.
-     *
-     * @param previous the previous snapshot head.
-     * @param layerBounds the region of the layer. Optional, if null, this is a normal save()
-     * @param paint the Paint information used to blit the layer back into the layers underneath
-     *          upon restore
-     * @param flags the flags regarding what should be saved.
-     */
-    private GcSnapshot(GcSnapshot previous, RectF layerBounds, Paint_Delegate paint, int flags) {
-        assert previous != null;
-        mPrevious = previous;
-        mFlags = flags;
-
-        // make a copy of the current layers before adding the new one.
-        // This keeps the same BufferedImage reference but creates new Graphics2D for this
-        // snapshot.
-        // It does not copy whatever original copy the layers have, as they will be done
-        // only if the new layer doesn't clip drawing to itself.
-        for (Layer layer : mPrevious.mLayers) {
-            mLayers.add(layer.makeCopy());
-        }
-
-        if (layerBounds != null) {
-            // get the current transform
-            AffineTransform matrix = mLayers.get(0).getGraphics().getTransform();
-
-            // transform the layerBounds with the current transform and stores it into a int rect
-            RectF rect2 = new RectF();
-            mapRect(matrix, rect2, layerBounds);
-            mLayerBounds = new Rect();
-            rect2.round(mLayerBounds);
-
-            // get the base layer (always at index 0)
-            Layer baseLayer = mLayers.get(0);
-
-            // create the image for the layer
-            BufferedImage layerImage = new BufferedImage(
-                    baseLayer.getImage().getWidth(),
-                    baseLayer.getImage().getHeight(),
-                    (mFlags & Canvas.HAS_ALPHA_LAYER_SAVE_FLAG) != 0 ?
-                            BufferedImage.TYPE_INT_ARGB :
-                                BufferedImage.TYPE_INT_RGB);
-
-            // create a graphics for it so that drawing can be done.
-            Graphics2D layerGraphics = layerImage.createGraphics();
-
-            // because this layer inherits the current context for transform and clip,
-            // set them to one from the base layer.
-            AffineTransform currentMtx = baseLayer.getGraphics().getTransform();
-            layerGraphics.setTransform(currentMtx);
-
-            // create a new layer for this new layer and add it to the list at the end.
-            mLayers.add(mLocalLayer = new Layer(layerGraphics, layerImage, flags));
-
-            // set the clip on it.
-            Shape currentClip = baseLayer.getGraphics().getClip();
-            mLocalLayer.setClip(currentClip);
-
-            // if the drawing is not clipped to the local layer only, we save the current content
-            // of all other layers. We are only interested in the part that will actually
-            // be drawn, so we create as small bitmaps as we can.
-            // This is so that we can erase the drawing that goes in the layers below that will
-            // be coming from the layer itself.
-            if ((mFlags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0) {
-                int w = mLayerBounds.width();
-                int h = mLayerBounds.height();
-                for (int i = 0 ; i < mLayers.size() - 1 ; i++) {
-                    Layer layer = mLayers.get(i);
-                    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-                    Graphics2D graphics = image.createGraphics();
-                    graphics.drawImage(layer.getImage(),
-                            0, 0, w, h,
-                            mLayerBounds.left, mLayerBounds.top,
-                                    mLayerBounds.right, mLayerBounds.bottom,
-                            null);
-                    graphics.dispose();
-                    layer.setOriginalCopy(image);
-                }
-            }
-        } else {
-            mLocalLayer = null;
-            mLayerBounds = null;
-        }
-
-        mLocalLayerPaint  = paint;
-    }
-
-    public void dispose() {
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        if (mPrevious != null) {
-            mPrevious.dispose();
-        }
-    }
-
-    /**
-     * Restores the top {@link GcSnapshot}, and returns the next one.
-     */
-    public GcSnapshot restore() {
-        return doRestore();
-    }
-
-    /**
-     * Restores the {@link GcSnapshot} to <var>saveCount</var>.
-     * @param saveCount the saveCount or -1 to only restore 1.
-     *
-     * @return the new head of the Gc snapshot stack.
-     */
-    public GcSnapshot restoreTo(int saveCount) {
-        return doRestoreTo(size(), saveCount);
-    }
-
-    public int size() {
-        if (mPrevious != null) {
-            return mPrevious.size() + 1;
-        }
-
-        return 1;
-    }
-
-    /**
-     * Link the snapshot to a Bitmap_Delegate.
-     * <p/>
-     * This is only for the case where the snapshot was created with a null image when calling
-     * {@link #createDefaultSnapshot(Bitmap_Delegate)}, and is therefore not yet linked to
-     * a previous snapshot.
-     * <p/>
-     * If any transform or clip information was set before, they are put into the Graphics object.
-     * @param bitmap the bitmap to link to.
-     */
-    public void setBitmap(Bitmap_Delegate bitmap) {
-        // create a new Layer for the bitmap. This will be the base layer.
-        Graphics2D graphics2D = bitmap.getImage().createGraphics();
-        Layer baseLayer = new Layer(graphics2D, bitmap);
-
-        // Set the current transform and clip which can either come from mTransform/mClip if they
-        // were set when there was no bitmap/layers or from the current base layers if there is
-        // one already.
-
-        graphics2D.setTransform(getTransform());
-        // reset mTransform in case there was one.
-        mTransform = null;
-
-        baseLayer.setClip(getClip());
-        // reset mClip in case there was one.
-        mClip = null;
-
-        // replace whatever current layers we have with this.
-        mLayers.clear();
-        mLayers.add(baseLayer);
-
-    }
-
-    public void translate(float dx, float dy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().translate(dx, dy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.translate(dx, dy);
-        }
-    }
-
-    public void rotate(double radians) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().rotate(radians);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.rotate(radians);
-        }
-    }
-
-    public void scale(float sx, float sy) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().scale(sx, sy);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.scale(sx, sy);
-        }
-    }
-
-    public AffineTransform getTransform() {
-        if (mLayers.size() > 0) {
-            // all graphics2D in the list have the same transform
-            return mLayers.get(0).getGraphics().getTransform();
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            return mTransform;
-        }
-    }
-
-    public void setTransform(AffineTransform transform) {
-        if (mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.getGraphics().setTransform(transform);
-            }
-        } else {
-            if (mTransform == null) {
-                mTransform = new AffineTransform();
-            }
-            mTransform.setTransform(transform);
-        }
-    }
-
-    public boolean clip(Shape shape, int regionOp) {
-        // Simple case of intersect with existing layers.
-        // Because Graphics2D#setClip works a bit peculiarly, we optimize
-        // the case of clipping by intersection, as it's supported natively.
-        if (regionOp == Region.Op.INTERSECT.nativeInt && mLayers.size() > 0) {
-            for (Layer layer : mLayers) {
-                layer.clip(shape);
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        }
-
-        Area area = null;
-
-        if (regionOp == Region.Op.REPLACE.nativeInt) {
-            area = new Area(shape);
-        } else {
-            area = Region_Delegate.combineShapes(getClip(), shape, regionOp);
-        }
-
-        assert area != null;
-
-        if (mLayers.size() > 0) {
-            if (area != null) {
-                for (Layer layer : mLayers) {
-                    layer.setClip(area);
-                }
-            }
-
-            Shape currentClip = getClip();
-            return currentClip != null && currentClip.getBounds().isEmpty() == false;
-        } else {
-            if (area != null) {
-                mClip = area;
-            } else {
-                mClip = new Area();
-            }
-
-            return mClip.getBounds().isEmpty() == false;
-        }
-    }
-
-    public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
-        return clip(new Rectangle2D.Float(left, top, right - left, bottom - top), regionOp);
-    }
-
-    /**
-     * Returns the current clip, or null if none have been setup.
-     */
-    public Shape getClip() {
-        if (mLayers.size() > 0) {
-            // they all have the same clip
-            return mLayers.get(0).getGraphics().getClip();
-        } else {
-            return mClip;
-        }
-    }
-
-    private GcSnapshot doRestoreTo(int size, int saveCount) {
-        if (size <= saveCount) {
-            return this;
-        }
-
-        // restore the current one first.
-        GcSnapshot previous = doRestore();
-
-        if (size == saveCount + 1) { // this was the only one that needed restore.
-            return previous;
-        } else {
-            return previous.doRestoreTo(size - 1, saveCount);
-        }
-    }
-
-    /**
-     * Executes the Drawable's draw method, with a null paint delegate.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     */
-    public void draw(Drawable drawable) {
-        draw(drawable, null, false /*compositeOnly*/, false /*forceSrcMode*/);
-    }
-
-    /**
-     * Executes the Drawable's draw method.
-     * <p/>
-     * Note that the method can be called several times if there are more than one active layer.
-     * @param compositeOnly whether the paint is used for composite only. This is typically
-     *          the case for bitmaps.
-     * @param forceSrcMode if true, this overrides the composite to be SRC
-     */
-    public void draw(Drawable drawable, Paint_Delegate paint, boolean compositeOnly,
-            boolean forceSrcMode) {
-        int forceMode = forceSrcMode ? AlphaComposite.SRC : 0;
-        // the current snapshot may not have a mLocalLayer (ie it was created on save() instead
-        // of saveLayer(), but that doesn't mean there's no layer.
-        // mLayers however saves all the information we need (flags).
-        if (mLayers.size() == 1) {
-            // no layer, only base layer. easy case.
-            drawInLayer(mLayers.get(0), drawable, paint, compositeOnly, forceMode);
-        } else {
-            // draw in all the layers until the layer save flags tells us to stop (ie drawing
-            // in that layer is limited to the layer itself.
-            int flags;
-            int i = mLayers.size() - 1;
-
-            do {
-                Layer layer = mLayers.get(i);
-
-                drawInLayer(layer, drawable, paint, compositeOnly, forceMode);
-
-                // then go to previous layer, only if there are any left, and its flags
-                // doesn't restrict drawing to the layer itself.
-                i--;
-                flags = layer.getFlags();
-            } while (i >= 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-        }
-    }
-
-    private void drawInLayer(Layer layer, Drawable drawable, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        Graphics2D originalGraphics = layer.getGraphics();
-        if (paint == null) {
-            drawOnGraphics((Graphics2D) originalGraphics.create(), drawable,
-                    null /*paint*/, layer);
-        } else {
-            ColorFilter_Delegate filter = paint.getColorFilter();
-            if (filter == null || !filter.isSupported()) {
-                // get a Graphics2D object configured with the drawing parameters.
-                Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                        compositeOnly, forceMode);
-                drawOnGraphics(configuredGraphics, drawable, paint, layer);
-                return;
-            }
-
-            int x = 0;
-            int y = 0;
-            int width;
-            int height;
-            Rectangle clipBounds = originalGraphics.getClip() != null ? originalGraphics
-                    .getClipBounds() : null;
-            if (clipBounds != null) {
-                if (clipBounds.width == 0 || clipBounds.height == 0) {
-                    // Clip is 0 so no need to paint anything.
-                    return;
-                }
-                // If we have clipBounds available, use them as they will always be
-                // smaller than the full layer size.
-                x = clipBounds.x;
-                y = clipBounds.y;
-                width = clipBounds.width;
-                height = clipBounds.height;
-            } else {
-                width = layer.getImage().getWidth();
-                height = layer.getImage().getHeight();
-            }
-
-            // Create a temporary image to which the color filter will be applied.
-            BufferedImage image = new BufferedImage(width, height,
-                    BufferedImage.TYPE_INT_ARGB);
-            Graphics2D imageBaseGraphics = (Graphics2D) image.getGraphics();
-            // Configure the Graphics2D object with drawing parameters and shader.
-            Graphics2D imageGraphics = createCustomGraphics(
-                    imageBaseGraphics, paint, compositeOnly,
-                    AlphaComposite.SRC_OVER);
-            // get a Graphics2D object configured with the drawing parameters, but no shader.
-            Graphics2D configuredGraphics = createCustomGraphics(originalGraphics, paint,
-                    true /*compositeOnly*/, forceMode);
-            try {
-                // The main draw operation.
-                // We translate the operation to take into account that the rendering does not
-                // know about the clipping area.
-                imageGraphics.translate(-x, -y);
-                drawable.draw(imageGraphics, paint);
-
-                // Apply the color filter.
-                // Restore the original coordinates system and apply the filter only to the
-                // clipped area.
-                imageGraphics.translate(x, y);
-                filter.applyFilter(imageGraphics, width, height);
-
-                // Draw the tinted image on the main layer using as start point the clipping
-                // upper left coordinates.
-                configuredGraphics.drawImage(image, x, y, null);
-                layer.change();
-            } finally {
-                // dispose Graphics2D objects
-                imageGraphics.dispose();
-                imageBaseGraphics.dispose();
-                configuredGraphics.dispose();
-            }
-        }
-    }
-
-    private void drawOnGraphics(Graphics2D g, Drawable drawable, Paint_Delegate paint,
-            Layer layer) {
-        try {
-            drawable.draw(g, paint);
-            layer.change();
-        } finally {
-            g.dispose();
-        }
-    }
-
-    private GcSnapshot doRestore() {
-        if (mPrevious != null) {
-            if (mLocalLayer != null) {
-                // prepare to blit the layers in which we have draw, in the layer beneath
-                // them, starting with the top one (which is the current local layer).
-                int i = mLayers.size() - 1;
-                int flags;
-                do {
-                    Layer dstLayer = mLayers.get(i - 1);
-
-                    restoreLayer(dstLayer);
-
-                    flags = dstLayer.getFlags();
-                    i--;
-                } while (i > 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
-            }
-
-            // if this snapshot does not save everything, then set the previous snapshot
-            // to this snapshot content
-
-            // didn't save the matrix? set the current matrix on the previous snapshot
-            if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
-                AffineTransform mtx = getTransform();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.getGraphics().setTransform(mtx);
-                }
-            }
-
-            // didn't save the clip? set the current clip on the previous snapshot
-            if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
-                Shape clip = getClip();
-                for (Layer layer : mPrevious.mLayers) {
-                    layer.setClip(clip);
-                }
-            }
-        }
-
-        for (Layer layer : mLayers) {
-            layer.getGraphics().dispose();
-        }
-
-        return mPrevious;
-    }
-
-    private void restoreLayer(Layer dstLayer) {
-
-        Graphics2D baseGfx = dstLayer.getImage().createGraphics();
-
-        // if the layer contains an original copy this means the flags
-        // didn't restrict drawing to the local layer and we need to make sure the
-        // layer bounds in the layer beneath didn't receive any drawing.
-        // so we use the originalCopy to erase the new drawings in there.
-        BufferedImage originalCopy = dstLayer.getOriginalCopy();
-        if (originalCopy != null) {
-            Graphics2D g = (Graphics2D) baseGfx.create();
-            g.setComposite(AlphaComposite.Src);
-
-            g.drawImage(originalCopy,
-                    mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                    0, 0, mLayerBounds.width(), mLayerBounds.height(),
-                    null);
-            g.dispose();
-        }
-
-        // now draw put the content of the local layer onto the layer,
-        // using the paint information
-        Graphics2D g = createCustomGraphics(baseGfx, mLocalLayerPaint,
-                true /*alphaOnly*/, 0 /*forceMode*/);
-
-        g.drawImage(mLocalLayer.getImage(),
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
-                null);
-        g.dispose();
-
-        baseGfx.dispose();
-    }
-
-    /**
-     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
-     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
-     */
-    private Graphics2D createCustomGraphics(Graphics2D original, Paint_Delegate paint,
-            boolean compositeOnly, int forceMode) {
-        // make new one graphics
-        Graphics2D g = (Graphics2D) original.create();
-
-        // configure it
-
-        if (paint.isAntiAliased()) {
-            g.setRenderingHint(
-                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setRenderingHint(
-                    RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-        }
-
-        // set the shader first, as it'll replace the color if it can be used it.
-        boolean customShader = false;
-        if (!compositeOnly) {
-            customShader = setShader(g, paint);
-            // set the stroke
-            g.setStroke(paint.getJavaStroke());
-        }
-        // set the composite.
-        setComposite(g, paint, compositeOnly || customShader, forceMode);
-
-        return g;
-    }
-
-    private boolean setShader(Graphics2D g, Paint_Delegate paint) {
-        Shader_Delegate shaderDelegate = paint.getShader();
-        if (shaderDelegate != null) {
-            if (shaderDelegate.isSupported()) {
-                java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
-                assert shaderPaint != null;
-                if (shaderPaint != null) {
-                    g.setPaint(shaderPaint);
-                    return true;
-                }
-            } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
-                        shaderDelegate.getSupportMessage(),
-                        null /*throwable*/, null /*data*/);
-            }
-        }
-
-        // if no shader, use the paint color
-        g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
-
-        return false;
-    }
-
-    private void setComposite(Graphics2D g, Paint_Delegate paint, boolean usePaintAlpha,
-            int forceMode) {
-        // the alpha for the composite. Always opaque if the normal paint color is used since
-        // it contains the alpha
-        int alpha = usePaintAlpha ? paint.getAlpha() : 0xFF;
-        if (forceMode != 0) {
-            g.setComposite(AlphaComposite.getInstance(forceMode, (float) alpha / 255.f));
-            return;
-        }
-        Mode mode = PorterDuff.intToMode(paint.getPorterDuffMode());
-        Composite composite = PorterDuffUtility.getComposite(mode, alpha);
-        g.setComposite(composite);
-    }
-
-    private void mapRect(AffineTransform matrix, RectF dst, RectF src) {
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        matrix.transform(corners, 0, corners, 0, 4);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-    }
-
-    /**
-     * Returns the clip of the oldest snapshot of the stack, appropriately translated to be
-     * expressed in the coordinate system of the latest snapshot.
-     */
-    public Rectangle getOriginalClip() {
-        GcSnapshot originalSnapshot = this;
-        while (originalSnapshot.mPrevious != null) {
-            originalSnapshot = originalSnapshot.mPrevious;
-        }
-        if (originalSnapshot.mLayers.isEmpty()) {
-            return null;
-        }
-        Graphics2D graphics2D = originalSnapshot.mLayers.get(0).getGraphics();
-        Rectangle bounds = graphics2D.getClipBounds();
-        if (bounds == null) {
-            return null;
-        }
-        try {
-            AffineTransform originalTransform =
-                    ((Graphics2D) graphics2D.create()).getTransform().createInverse();
-            AffineTransform latestTransform = getTransform().createInverse();
-            bounds.x += latestTransform.getTranslateX() - originalTransform.getTranslateX();
-            bounds.y += latestTransform.getTranslateY() - originalTransform.getTranslateY();
-        } catch (NoninvertibleTransformException e) {
-            Bridge.getLog().warning(null, "Non invertible transformation", null);
-        }
-        return bounds;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
deleted file mode 100644
index 287334c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.bars.AppCompatActionBar;
-import com.android.layoutlib.bridge.bars.BridgeActionBar;
-import com.android.layoutlib.bridge.bars.Config;
-import com.android.layoutlib.bridge.bars.FrameworkActionBar;
-import com.android.layoutlib.bridge.bars.NavigationBar;
-import com.android.layoutlib.bridge.bars.StatusBar;
-import com.android.layoutlib.bridge.bars.TitleBar;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-
-import android.annotation.NonNull;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.AttachInfo_Accessor;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.ViewRootImpl_Accessor;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.widget.LinearLayout.VERTICAL;
-import static com.android.layoutlib.bridge.impl.ResourceHelper.getBooleanThemeValue;
-
-/**
- * The Layout used to create the system decor.
- *
- * The layout inflated will contain a content frame where the user's layout can be inflated.
- * <pre>
- *  +-------------------------------------------------+---+
- *  | Status bar                                      | N |
- *  +-------------------------------------------------+ a |
- *  | Title/Action bar (optional)                     | v |
- *  +-------------------------------------------------+   |
- *  | Content, vertical extending                     | b |
- *  |                                                 | a |
- *  |                                                 | r |
- *  +-------------------------------------------------+---+
- * </pre>
- * or
- * <pre>
- *  +-------------------------------------+
- *  | Status bar                          |
- *  +-------------------------------------+
- *  | Title/Action bar (optional)         |
- *  +-------------------------------------+
- *  | Content, vertical extending         |
- *  |                                     |
- *  |                                     |
- *  +-------------------------------------+
- *  | Nav bar                             |
- *  +-------------------------------------+
- * </pre>
- *
- */
-class Layout extends RelativeLayout {
-
-    // Theme attributes used for configuring appearance of the system decor.
-    private static final String ATTR_WINDOW_FLOATING = "windowIsFloating";
-    private static final String ATTR_WINDOW_BACKGROUND = "windowBackground";
-    private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullscreen";
-    private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height";
-    private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width";
-    private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height";
-    private static final String ATTR_WINDOW_ACTION_BAR = "windowActionBar";
-    private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize";
-    private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle";
-    private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize";
-    private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT;
-    private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT;
-
-    // Default sizes
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_NAV_BAR_SIZE = 48;
-
-    // Ids assigned to components created. This is so that we can refer to other components in
-    // layout params.
-    private static final String ID_NAV_BAR = "navBar";
-    private static final String ID_STATUS_BAR = "statusBar";
-    private static final String ID_TITLE_BAR = "titleBar";
-    // Prefix used with the above ids in order to make them unique in framework namespace.
-    private static final String ID_PREFIX = "android_layoutlib_";
-
-    /**
-     * Temporarily store the builder so that it doesn't have to be passed to all methods used
-     * during inflation.
-     */
-    private Builder mBuilder;
-
-    /**
-     * This holds user's layout.
-     */
-    private FrameLayout mContentRoot;
-
-    public Layout(@NonNull Builder builder) {
-        super(builder.mContext);
-        mBuilder = builder;
-        if (builder.mWindowBackground != null) {
-            Drawable d = ResourceHelper.getDrawable(builder.mWindowBackground, builder.mContext);
-            setBackground(d);
-        }
-
-        int simulatedPlatformVersion = getParams().getSimulatedPlatformVersion();
-        HardwareConfig hwConfig = getParams().getHardwareConfig();
-        Density density = hwConfig.getDensity();
-        boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale());
-        setLayoutDirection(isRtl? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR);
-
-        NavigationBar navBar = null;
-        if (mBuilder.hasNavBar()) {
-            navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        StatusBar statusBar = null;
-        if (builder.mStatusBarSize > 0) {
-            statusBar = createStatusBar(getContext(), density, isRtl, getParams().isRtlSupported(),
-                    simulatedPlatformVersion);
-        }
-
-        View actionBar = null;
-        TitleBar titleBar = null;
-        if (builder.mActionBarSize > 0) {
-            BridgeActionBar bar = createActionBar(getContext(), getParams());
-            mContentRoot = bar.getContentRoot();
-            actionBar = bar.getRootView();
-        } else if (mBuilder.mTitleBarSize > 0) {
-            titleBar = createTitleBar(getContext(), getParams().getAppLabel(),
-                    simulatedPlatformVersion);
-        }
-
-        addViews(titleBar, mContentRoot == null ? (mContentRoot = createContentFrame()) : actionBar,
-                statusBar, navBar);
-        // Done with the builder. Don't hold a reference to it.
-        mBuilder = null;
-     }
-
-    @NonNull
-    private FrameLayout createContentFrame() {
-        FrameLayout contentRoot = new FrameLayout(getContext());
-        LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            params.addRule(rule, getId(ID_NAV_BAR));
-        }
-        int below = -1;
-        if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) {
-            below = getId(ID_TITLE_BAR);
-        } else if (mBuilder.hasSolidStatusBar()) {
-            below = getId(ID_STATUS_BAR);
-        }
-        if (below != -1) {
-            params.addRule(BELOW, below);
-        }
-        contentRoot.setLayoutParams(params);
-        return contentRoot;
-    }
-
-    @NonNull
-    private LayoutParams createLayoutParams(int width, int height) {
-        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
-        if (width > 0) {
-            width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics);
-        }
-        if (height > 0) {
-            height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics);
-        }
-        return new LayoutParams(width, height);
-    }
-
-    @NonNull
-    public FrameLayout getContentRoot() {
-        return mContentRoot;
-    }
-
-    @NonNull
-    private SessionParams getParams() {
-        return mBuilder.mParams;
-    }
-
-    @NonNull
-    @Override
-    public BridgeContext getContext(){
-        return (BridgeContext) super.getContext();
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private StatusBar createStatusBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        StatusBar statusBar =
-                new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize);
-        if (mBuilder.isNavBarVertical()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        statusBar.setLayoutParams(params);
-        statusBar.setId(getId(ID_STATUS_BAR));
-        return statusBar;
-    }
-
-    private BridgeActionBar createActionBar(@NonNull BridgeContext context,
-            @NonNull SessionParams params) {
-        boolean isMenu = "menu".equals(params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-
-        BridgeActionBar actionBar;
-        if (context.isAppCompatTheme() && !isMenu) {
-            actionBar = new AppCompatActionBar(context, params);
-        } else {
-            actionBar = new FrameworkActionBar(context, params);
-        }
-        LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT);
-        int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE;
-        if (mBuilder.hasSolidNavBar()) {
-            layoutParams.addRule(rule, getId(ID_NAV_BAR));
-        }
-        if (mBuilder.hasSolidStatusBar()) {
-            layoutParams.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        actionBar.getRootView().setLayoutParams(layoutParams);
-        actionBar.createMenuPopup();
-        return actionBar;
-    }
-
-    @NonNull
-    private TitleBar createTitleBar(BridgeContext context, String title,
-            int simulatedPlatformVersion) {
-        TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion);
-        LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize);
-        if (mBuilder.hasSolidStatusBar()) {
-            params.addRule(BELOW, getId(ID_STATUS_BAR));
-        }
-        if (mBuilder.isNavBarVertical() && mBuilder.hasSolidNavBar()) {
-            params.addRule(START_OF, getId(ID_NAV_BAR));
-        }
-        titleBar.setLayoutParams(params);
-        titleBar.setId(getId(ID_TITLE_BAR));
-        return titleBar;
-    }
-
-    /**
-     * @param isRtl    whether the current locale is an RTL locale.
-     * @param isRtlSupported    whether the applications supports RTL (i.e. has supportsRtl=true
-     * in the manifest and targetSdkVersion >= 17.
-     */
-    @NonNull
-    private NavigationBar createNavBar(BridgeContext context, Density density, boolean isRtl,
-            boolean isRtlSupported, int simulatedPlatformVersion) {
-        int orientation = mBuilder.mNavBarOrientation;
-        int size = mBuilder.mNavBarSize;
-        NavigationBar navBar = new NavigationBar(context, density, orientation, isRtl,
-                isRtlSupported, simulatedPlatformVersion);
-        boolean isVertical = mBuilder.isNavBarVertical();
-        int w = isVertical ? size : MATCH_PARENT;
-        int h = isVertical ? MATCH_PARENT : size;
-        LayoutParams params = createLayoutParams(w, h);
-        params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM);
-        navBar.setLayoutParams(params);
-        navBar.setId(getId(ID_NAV_BAR));
-        return navBar;
-    }
-
-    private void addViews(@NonNull View... views) {
-        for (View view : views) {
-            if (view != null) {
-                addView(view);
-            }
-        }
-    }
-
-    private int getId(String name) {
-        return Bridge.getResourceId(ResourceType.ID, ID_PREFIX + name);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Override
-    public void requestFitSystemWindows() {
-        // The framework call would usually bubble up to ViewRootImpl but, in layoutlib, Layout will
-        // act as view root for most purposes. That way, we can also save going through the Handler
-        // to dispatch the new applied insets.
-        ViewRootImpl root = AttachInfo_Accessor.getRootView(this);
-        if (root != null) {
-            ViewRootImpl_Accessor.dispatchApplyInsets(root, this);
-        }
-    }
-
-    /**
-     * A helper class to help initialize the Layout.
-     */
-    static class Builder {
-        @NonNull
-        private final SessionParams mParams;
-        @NonNull
-        private final BridgeContext mContext;
-        private final RenderResources mResources;
-        
-        private final boolean mWindowIsFloating;
-        private ResourceValue mWindowBackground;
-        private int mStatusBarSize;
-        private int mNavBarSize;
-        private int mNavBarOrientation;
-        private int mActionBarSize;
-        private int mTitleBarSize;
-        private boolean mTranslucentStatus;
-        private boolean mTranslucentNav;
-
-        public Builder(@NonNull SessionParams params, @NonNull BridgeContext context) {
-            mParams = params;
-            mContext = context;
-            mResources = mParams.getResources();
-            mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true);
-            
-            findBackground();
-
-            if (!mParams.isForceNoDecor()) {
-                findStatusBar();
-                findActionBar();
-                findNavBar();
-            }
-        }
-
-        private void findBackground() {
-            if (!mParams.isBgColorOverridden()) {
-                mWindowBackground = mResources.findItemInTheme(ATTR_WINDOW_BACKGROUND, true);
-                mWindowBackground = mResources.resolveResValue(mWindowBackground);
-            }
-        }
-
-        private void findStatusBar() {
-            boolean windowFullScreen =
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false);
-            if (!windowFullScreen && !mWindowIsFloating) {
-                mStatusBarSize =
-                        getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT);
-                mTranslucentStatus = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_STATUS, true, false);
-            }
-        }
-
-        private void  findActionBar() {
-            if (mWindowIsFloating) {
-                return;
-            }
-            // Check if an actionbar is needed
-            boolean isMenu = "menu".equals(mParams.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG));
-            boolean windowActionBar = isMenu ||
-                    getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR,
-                            !mContext.isAppCompatTheme(), true);
-            if (windowActionBar) {
-                mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-            } else {
-                // Maybe the gingerbread era title bar is needed
-                boolean windowNoTitle =
-                        getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false);
-                if (!windowNoTitle) {
-                    mTitleBarSize =
-                            getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT);
-                }
-            }
-        }
-
-        private void findNavBar() {
-            if (hasSoftwareButtons() && !mWindowIsFloating) {
-
-                // get orientation
-                HardwareConfig hwConfig = mParams.getHardwareConfig();
-                boolean barOnBottom = true;
-
-                if (hwConfig.getOrientation() == ScreenOrientation.LANDSCAPE) {
-                    int shortSize = hwConfig.getScreenHeight();
-                    int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT /
-                            hwConfig.getDensity().getDpiValue();
-
-                    // 0-599dp: "phone" UI with bar on the side
-                    // 600+dp: "tablet" UI with bar on the bottom
-                    barOnBottom = shortSizeDp >= 600;
-                }
-
-                mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL;
-                mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH,
-                        true, DEFAULT_NAV_BAR_SIZE);
-                mTranslucentNav = getBooleanThemeValue(mResources,
-                        ATTR_WINDOW_TRANSLUCENT_NAV, true, false);
-            }
-        }
-
-        @SuppressWarnings("SameParameterValue")
-        private int getDimension(String attr, boolean isFramework, int defaultValue) {
-            ResourceValue value = mResources.findItemInTheme(attr, isFramework);
-            value = mResources.resolveResValue(value);
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(attr, value.getValue(), true);
-                if (typedValue != null) {
-                    return (int) typedValue.getDimension(mContext.getMetrics());
-                }
-            }
-            return defaultValue;
-        }
-
-        private boolean hasSoftwareButtons() {
-            return mParams.getHardwareConfig().hasSoftwareButtons();
-        }
-
-        /**
-         * Return true if the nav bar is present and not translucent
-         */
-        private boolean hasSolidNavBar() {
-            return hasNavBar() && !mTranslucentNav;
-        }
-
-        /**
-         * Return true if the status bar is present and not translucent
-         */
-        private boolean hasSolidStatusBar() {
-            return hasStatusBar() && !mTranslucentStatus;
-        }
-
-        private boolean hasNavBar() {
-            return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) &&
-                    hasSoftwareButtons() && mNavBarSize > 0;
-        }
-
-        private boolean hasStatusBar() {
-            return mStatusBarSize > 0;
-        }
-
-        /**
-         * Return true if the nav bar is present and is vertical.
-         */
-        private boolean isNavBarVertical() {
-            return hasNavBar() && mNavBarOrientation == VERTICAL;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
deleted file mode 100644
index 71e7fd2..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutParserWrapper.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A wrapper around XmlPullParser that can peek forward to inspect if the file is a data-binding
- * layout and some parts need to be stripped.
- */
-public class LayoutParserWrapper implements XmlPullParser {
-
-    // Data binding constants.
-    private static final String TAG_LAYOUT = "layout";
-    private static final String TAG_DATA = "data";
-    private static final String DEFAULT = "default=";
-
-    private final XmlPullParser mDelegate;
-
-    // Storage for peeked values.
-    private boolean mPeeked;
-    private int mEventType;
-    private int mDepth;
-    private int mNext;
-    private List<Attribute> mAttributes;
-    private String mText;
-    private String mName;
-
-    // Used to end the document before the actual parser ends.
-    private int mFinalDepth = -1;
-    private boolean mEndNow;
-
-    public LayoutParserWrapper(XmlPullParser delegate) {
-        mDelegate = delegate;
-    }
-
-    public LayoutParserWrapper peekTillLayoutStart() throws IOException, XmlPullParserException {
-        final int STATE_LAYOUT_NOT_STARTED = 0;  // <layout> tag not encountered yet.
-        final int STATE_ROOT_NOT_STARTED = 1;    // the main view root not found yet.
-        final int STATE_INSIDE_DATA = 2;         // START_TAG for <data> found, but not END_TAG.
-
-        int state = STATE_LAYOUT_NOT_STARTED;
-        int dataDepth = -1;    // depth of the <data> tag. Should be two.
-        while (true) {
-            int peekNext = peekNext();
-            switch (peekNext) {
-                case START_TAG:
-                    if (state == STATE_LAYOUT_NOT_STARTED) {
-                        if (mName.equals(TAG_LAYOUT)) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        } else {
-                            return this; // no layout tag in the file.
-                        }
-                    } else if (state == STATE_ROOT_NOT_STARTED) {
-                        if (mName.equals(TAG_DATA)) {
-                            state = STATE_INSIDE_DATA;
-                            dataDepth = mDepth;
-                        } else {
-                            mFinalDepth = mDepth;
-                            return this;
-                        }
-                    }
-                    break;
-                case END_TAG:
-                    if (state == STATE_INSIDE_DATA) {
-                        if (mDepth <= dataDepth) {
-                            state = STATE_ROOT_NOT_STARTED;
-                        }
-                    }
-                    break;
-                case END_DOCUMENT:
-                    // No layout start found.
-                    return this;
-            }
-            // consume the peeked tag.
-            next();
-        }
-    }
-
-    private int peekNext() throws IOException, XmlPullParserException {
-        if (mPeeked) {
-            return mNext;
-        }
-        mEventType = mDelegate.getEventType();
-        mNext = mDelegate.next();
-        if (mEventType == START_TAG) {
-            int count = mDelegate.getAttributeCount();
-            mAttributes = count > 0 ? new ArrayList<Attribute>(count) :
-                    Collections.<Attribute>emptyList();
-            for (int i = 0; i < count; i++) {
-                mAttributes.add(new Attribute(mDelegate.getAttributeNamespace(i),
-                        mDelegate.getAttributeName(i), mDelegate.getAttributeValue(i)));
-            }
-        }
-        mDepth = mDelegate.getDepth();
-        mText = mDelegate.getText();
-        mName = mDelegate.getName();
-        mPeeked = true;
-        return mNext;
-    }
-
-    private void reset() {
-        mAttributes = null;
-        mText = null;
-        mName = null;
-        mPeeked = false;
-    }
-
-    @Override
-    public int next() throws XmlPullParserException, IOException {
-        int returnValue;
-        int depth;
-        if (mPeeked) {
-            returnValue = mNext;
-            depth = mDepth;
-            reset();
-        } else if (mEndNow) {
-            return END_DOCUMENT;
-        } else {
-            returnValue = mDelegate.next();
-            depth = getDepth();
-        }
-        if (returnValue == END_TAG && depth <= mFinalDepth) {
-            mEndNow = true;
-        }
-        return returnValue;
-    }
-
-    @Override
-    public int getEventType() throws XmlPullParserException {
-        return mPeeked ? mEventType : mDelegate.getEventType();
-    }
-
-    @Override
-    public int getDepth() {
-        return mPeeked ? mDepth : mDelegate.getDepth();
-    }
-
-    @Override
-    public String getName() {
-        return mPeeked ? mName : mDelegate.getName();
-    }
-
-    @Override
-    public String getText() {
-        return mPeeked ? mText : mDelegate.getText();
-    }
-
-    @Override
-    public String getAttributeValue(@Nullable String namespace, String name) {
-        String returnValue = null;
-        if (mPeeked) {
-            if (mAttributes == null) {
-                if (mEventType != START_TAG) {
-                    throw new IndexOutOfBoundsException("getAttributeValue() called when not at START_TAG.");
-                } else {
-                    return null;
-                }
-            } else {
-                for (Attribute attribute : mAttributes) {
-                    //noinspection StringEquality for nullness check.
-                    if (attribute.name.equals(name) && (attribute.namespace == namespace ||
-                            attribute.namespace != null && attribute.namespace.equals(namespace))) {
-                        returnValue = attribute.value;
-                        break;
-                    }
-                }
-            }
-        } else {
-            returnValue = mDelegate.getAttributeValue(namespace, name);
-        }
-        // Check if the value is bound via data-binding, if yes get the default value.
-        if (returnValue != null && mFinalDepth >= 0 && returnValue.startsWith("@{")) {
-            // TODO: Improve the detection of default keyword.
-            int i = returnValue.lastIndexOf(DEFAULT);
-            return i > 0 ? returnValue.substring(i + DEFAULT.length(), returnValue.length() - 1)
-                    : null;
-        }
-        return returnValue;
-    }
-
-    private static class Attribute {
-        @Nullable
-        public final String namespace;
-        public final String name;
-        public final String value;
-
-        public Attribute(@Nullable String namespace, String name, String value) {
-            this.namespace = namespace;
-            this.name = name;
-            this.value = value;
-        }
-    }
-
-    // Not affected by peeking.
-
-    @Override
-    public void setFeature(String s, boolean b) throws XmlPullParserException {
-        mDelegate.setFeature(s, b);
-    }
-
-    @Override
-    public void setProperty(String s, Object o) throws XmlPullParserException {
-        mDelegate.setProperty(s, o);
-    }
-
-    @Override
-    public void setInput(InputStream inputStream, String s) throws XmlPullParserException {
-        mDelegate.setInput(inputStream, s);
-    }
-
-    @Override
-    public void setInput(Reader reader) throws XmlPullParserException {
-        mDelegate.setInput(reader);
-    }
-
-    @Override
-    public String getInputEncoding() {
-        return mDelegate.getInputEncoding();
-    }
-
-    @Override
-    public String getNamespace(String s) {
-        return mDelegate.getNamespace(s);
-    }
-
-    @Override
-    public String getPositionDescription() {
-        return mDelegate.getPositionDescription();
-    }
-
-    @Override
-    public int getLineNumber() {
-        return mDelegate.getLineNumber();
-    }
-
-    @Override
-    public String getNamespace() {
-        return mDelegate.getNamespace();
-    }
-
-    @Override
-    public int getColumnNumber() {
-        return mDelegate.getColumnNumber();
-    }
-
-    // -- We don't care much about the methods that follow.
-
-    @Override
-    public void require(int i, String s, String s1) throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean getFeature(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public void defineEntityReplacementText(String s, String s1) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public Object getProperty(String s) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextToken() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getNamespaceCount(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespacePrefix(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getNamespaceUri(int i) throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isWhitespace() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public char[] getTextCharacters(int[] ints) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getPrefix() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isEmptyElementTag() throws XmlPullParserException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int getAttributeCount() {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeNamespace(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeName(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributePrefix(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeType(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public boolean isAttributeDefault(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String getAttributeValue(int i) {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public String nextText() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-
-    @Override
-    public int nextTag() throws XmlPullParserException, IOException {
-        throw new UnsupportedOperationException("Only few parser methods are supported.");
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
deleted file mode 100644
index 1ae9cb6..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A factory for {@link XmlPullParser}.
- *
- */
-public class ParserFactory {
-
-    public final static boolean LOG_PARSER = false;
-
-    // Used to get a new XmlPullParser from the client.
-    @Nullable
-    private static com.android.ide.common.rendering.api.ParserFactory sParserFactory;
-
-    public static void setParserFactory(
-            @Nullable com.android.ide.common.rendering.api.ParserFactory parserFactory) {
-        sParserFactory = parserFactory;
-    }
-
-    @NonNull
-    public static XmlPullParser create(@NonNull File f)
-            throws XmlPullParserException, FileNotFoundException {
-        return create(f, false);
-    }
-
-    public static XmlPullParser create(@NonNull File f, boolean isLayout)
-      throws XmlPullParserException, FileNotFoundException {
-        InputStream stream = new FileInputStream(f);
-        return create(stream, f.getName(), f.length(), isLayout);
-    }
-    @NonNull
-    public static XmlPullParser create(@NonNull InputStream stream, @Nullable String name)
-        throws XmlPullParserException {
-        return create(stream, name, -1, false);
-    }
-
-    @NonNull
-    private static XmlPullParser create(@NonNull InputStream stream, @Nullable String name,
-            long size, boolean isLayout) throws XmlPullParserException {
-        XmlPullParser parser = instantiateParser(name);
-
-        stream = readAndClose(stream, name, size);
-
-        parser.setInput(stream, null);
-        if (isLayout) {
-            try {
-                return new LayoutParserWrapper(parser).peekTillLayoutStart();
-            } catch (IOException e) {
-                throw new XmlPullParserException(null, parser, e);
-            }
-        }
-        return parser;
-    }
-
-    @NonNull
-    public static XmlPullParser instantiateParser(@Nullable String name)
-            throws XmlPullParserException {
-        if (sParserFactory == null) {
-            throw new XmlPullParserException("ParserFactory not initialized.");
-        }
-        XmlPullParser parser = sParserFactory.createParser(name);
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        return parser;
-    }
-
-    @NonNull
-    private static InputStream readAndClose(@NonNull InputStream stream, @Nullable String name,
-            long size) throws XmlPullParserException {
-        // just a sanity check. It's doubtful we'll have such big files!
-        if (size > Integer.MAX_VALUE) {
-            throw new XmlPullParserException("File " + name + " is too big to be parsed");
-        }
-        int intSize = (int) size;
-
-        // create a buffered reader to facilitate reading.
-        BufferedInputStream bufferedStream = new BufferedInputStream(stream);
-        try {
-            int avail;
-            if (intSize != -1) {
-                avail = intSize;
-            } else {
-                // get the size to read.
-                avail = bufferedStream.available();
-            }
-
-            // create the initial buffer and read it.
-            byte[] buffer = new byte[avail];
-            int read = stream.read(buffer);
-
-            // this is the easy case.
-            if (read == intSize) {
-                return new ByteArrayInputStream(buffer);
-            }
-
-            // check if there is more to read (read() does not necessarily read all that
-            // available() returned!)
-            while ((avail = bufferedStream.available()) > 0) {
-                if (read + avail > buffer.length) {
-                    // just allocate what is needed. We're mostly reading small files
-                    // so it shouldn't be too problematic.
-                    byte[] moreBuffer = new byte[read + avail];
-                    System.arraycopy(buffer, 0, moreBuffer, 0, read);
-                    buffer = moreBuffer;
-                }
-
-                read += stream.read(buffer, read, avail);
-            }
-
-            // return a new stream encapsulating this buffer.
-            return new ByteArrayInputStream(buffer);
-
-        } catch (IOException e) {
-            throw new XmlPullParserException("Failed to read " + name, null, e);
-        } finally {
-            try {
-                bufferedStream.close();
-            } catch (IOException ignored) {
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
deleted file mode 100644
index 7b70180..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PlayAnimationThread.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-
-public class PlayAnimationThread extends AnimationThread {
-
-    private final Animator mAnimator;
-
-    public PlayAnimationThread(Animator animator, RenderSessionImpl scene, String animName,
-            IAnimationListener listener) {
-        super(scene, animName, listener);
-        mAnimator = animator;
-    }
-
-    @Override
-    public Result preAnimation() {
-        // start the animation. This will send a message to the handler right away, so
-        // the queue is filled when this method returns.
-        mAnimator.start();
-
-        return Status.SUCCESS.createResult();
-    }
-
-    @Override
-    public void postAnimation() {
-        // nothing to be done.
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
deleted file mode 100644
index 70e2eb1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.graphics.BlendComposite;
-import android.graphics.BlendComposite.BlendingMode;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter_Delegate;
-
-import java.awt.AlphaComposite;
-import java.awt.Composite;
-
-/**
- * Provides various utility methods for {@link PorterDuffColorFilter_Delegate}.
- */
-public final class PorterDuffUtility {
-
-    private static final int MODES_COUNT = Mode.values().length;
-
-    // Make the class non-instantiable.
-    private PorterDuffUtility() {
-    }
-
-    /**
-     * Convert the porterDuffMode from the framework to its corresponding enum. This defaults to
-     * {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Mode getPorterDuffMode(int porterDuffMode) {
-        if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
-            return PorterDuff.intToMode(porterDuffMode);
-        }
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null);
-        assert false;
-        return Mode.SRC_OVER;
-    }
-
-    /**
-     * A utility method to get the {@link Composite} that represents the filter for the given
-     * PorterDuff mode and the alpha. Defaults to {@link Mode#SRC_OVER} for invalid modes.
-     */
-    public static Composite getComposite(Mode mode, int alpha255) {
-        float alpha1 = alpha255 != 0xFF ? alpha255 / 255.f : 1.f;
-        switch (mode) {
-            case CLEAR:
-                return AlphaComposite.getInstance(AlphaComposite.CLEAR, alpha1);
-            case SRC:
-                return AlphaComposite.getInstance(AlphaComposite.SRC, alpha1);
-            case DST:
-                return AlphaComposite.getInstance(AlphaComposite.DST, alpha1);
-            case SRC_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-            case DST_OVER:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, alpha1);
-            case SRC_IN:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha1);
-            case DST_IN:
-                return AlphaComposite.getInstance(AlphaComposite.DST_IN, alpha1);
-            case SRC_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, alpha1);
-            case DST_OUT:
-                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, alpha1);
-            case SRC_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha1);
-            case DST_ATOP:
-                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, alpha1);
-            case XOR:
-                return AlphaComposite.getInstance(AlphaComposite.XOR, alpha1);
-            case DARKEN:
-                return BlendComposite.getInstance(BlendingMode.DARKEN, alpha1);
-            case LIGHTEN:
-                return BlendComposite.getInstance(BlendingMode.LIGHTEN, alpha1);
-            case MULTIPLY:
-                return BlendComposite.getInstance(BlendingMode.MULTIPLY, alpha1);
-            case SCREEN:
-                return BlendComposite.getInstance(BlendingMode.SCREEN, alpha1);
-            case ADD:
-                return BlendComposite.getInstance(BlendingMode.ADD, alpha1);
-            case OVERLAY:
-                return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1);
-            default:
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
-                        String.format("Unsupported PorterDuff Mode: %1$s", mode.name()),
-                        null, null /*data*/);
-
-                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha1);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
deleted file mode 100644
index 0c53753..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-import com.android.resources.ResourceType;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRound;
-import com.android.resources.ScreenSize;
-
-import android.content.res.Configuration;
-import android.os.HandlerThread_Delegate;
-import android.util.DisplayMetrics;
-import android.view.ViewConfiguration_Accessor;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodManager_Accessor;
-
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
-/**
- * Base class for rendering action.
- *
- * It provides life-cycle methods to init and stop the rendering.
- * The most important methods are:
- * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
- * after the rendering.
- *
- *
- * @param <T> the {@link RenderParams} implementation
- *
- */
-public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
-
-    /**
-     * The current context being rendered. This is set through {@link #acquire(long)} and
-     * {@link #init(long)}, and unset in {@link #release()}.
-     */
-    private static BridgeContext sCurrentContext = null;
-
-    private final T mParams;
-
-    private BridgeContext mContext;
-
-    /**
-     * Creates a renderAction.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderAction#init(long)}, which act as a
-     * call to {@link RenderAction#acquire(long)}
-     *
-     * @param params the RenderParams. This must be a copy that the action can keep
-     *
-     */
-    protected RenderAction(T params) {
-        mParams = params;
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    public Result init(long timeout) {
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        HardwareConfig hardwareConfig = mParams.getHardwareConfig();
-
-        // setup the display Metrics.
-        DisplayMetrics metrics = new DisplayMetrics();
-        metrics.densityDpi = metrics.noncompatDensityDpi =
-                hardwareConfig.getDensity().getDpiValue();
-
-        metrics.density = metrics.noncompatDensity =
-                metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
-
-        metrics.scaledDensity = metrics.noncompatScaledDensity = metrics.density;
-
-        metrics.widthPixels = metrics.noncompatWidthPixels = hardwareConfig.getScreenWidth();
-        metrics.heightPixels = metrics.noncompatHeightPixels = hardwareConfig.getScreenHeight();
-        metrics.xdpi = metrics.noncompatXdpi = hardwareConfig.getXdpi();
-        metrics.ydpi = metrics.noncompatYdpi = hardwareConfig.getYdpi();
-
-        RenderResources resources = mParams.getResources();
-
-        // build the context
-        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
-                mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(mParams),
-                mParams.getTargetSdkVersion(), mParams.isRtlSupported());
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Prepares the scene for action.
-     * <p>
-     * This call is blocking if another rendering/inflating is currently happening, and will return
-     * whether the preparation worked.
-     *
-     * The preparation can fail if another rendering took too long and the timeout was elapsed.
-     *
-     * More than one call to this from the same thread will have no effect and will return
-     * {@link Result.Status#SUCCESS}.
-     *
-     * After scene actions have taken place, only one call to {@link #release()} must be
-     * done.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #release()
-     *
-     * @throws IllegalStateException if {@link #init(long)} was never called.
-     */
-    public Result acquire(long timeout) {
-        if (mContext == null) {
-            throw new IllegalStateException("After scene creation, #init() must be called");
-        }
-
-        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
-        // the result.
-        Result result = acquireLock(timeout);
-        if (result != null) {
-            return result;
-        }
-
-        setUp();
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Acquire the lock so that the scene can be acted upon.
-     * <p>
-     * This returns null if the lock was just acquired, otherwise it returns
-     * {@link Result.Status#SUCCESS} if the lock already belonged to that thread, or another
-     * instance (see {@link Result#getStatus()}) if an error occurred.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     * @return null if the lock was just acquire or another result depending on the state.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene.
-     */
-    private Result acquireLock(long timeout) {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            try {
-                boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
-
-                if (!acquired) {
-                    return ERROR_TIMEOUT.createResult();
-                }
-            } catch (InterruptedException e) {
-                return ERROR_LOCK_INTERRUPTED.createResult();
-            }
-        } else {
-            // This thread holds the lock already. Checks that this wasn't for a different context.
-            // If this is called by init, mContext will be null and so should sCurrentContext
-            // anyway
-            if (mContext != sCurrentContext) {
-                throw new IllegalStateException("Acquiring different scenes from same thread without releases");
-            }
-            return SUCCESS.createResult();
-        }
-
-        return null;
-    }
-
-    /**
-     * Cleans up the scene after an action.
-     */
-    public void release() {
-        ReentrantLock lock = Bridge.getLock();
-
-        // with the use of finally blocks, it is possible to find ourself calling this
-        // without a successful call to prepareScene. This test makes sure that unlock() will
-        // not throw IllegalMonitorStateException.
-        if (lock.isHeldByCurrentThread()) {
-            tearDown();
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Sets up the session for rendering.
-     * <p/>
-     * The counterpart is {@link #tearDown()}.
-     */
-    private void setUp() {
-        // setup the ParserFactory
-        ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory());
-
-        // make sure the Resources object references the context (and other objects) for this
-        // scene
-        mContext.initResources();
-        sCurrentContext = mContext;
-
-        // create an InputMethodManager
-        InputMethodManager.getInstance();
-
-        LayoutLog currentLog = mParams.getLog();
-        Bridge.setLog(currentLog);
-        mContext.getRenderResources().setFrameworkResourceIdProvider(this);
-        mContext.getRenderResources().setLogger(currentLog);
-    }
-
-    /**
-     * Tear down the session after rendering.
-     * <p/>
-     * The counterpart is {@link #setUp()}.
-     */
-    private void tearDown() {
-        // The context may be null, if there was an error during init().
-        if (mContext != null) {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            mContext.disposeResources();
-        }
-
-        if (sCurrentContext != null) {
-            // quit HandlerThread created during this session.
-            HandlerThread_Delegate.cleanUp(sCurrentContext);
-        }
-
-        // clear the stored ViewConfiguration since the map is per density and not per context.
-        ViewConfiguration_Accessor.clearConfigurations();
-
-        // remove the InputMethodManager
-        InputMethodManager_Accessor.resetInstance();
-
-        sCurrentContext = null;
-
-        Bridge.setLog(null);
-        if (mContext != null) {
-            mContext.getRenderResources().setFrameworkResourceIdProvider(null);
-            mContext.getRenderResources().setLogger(null);
-        }
-        ParserFactory.setParserFactory(null);
-    }
-
-    public static BridgeContext getCurrentContext() {
-        return sCurrentContext;
-    }
-
-    protected T getParams() {
-        return mParams;
-    }
-
-    protected BridgeContext getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the log associated with the session.
-     * @return the log or null if there are none.
-     */
-    public LayoutLog getLog() {
-        if (mParams != null) {
-            return mParams.getLog();
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks that the lock is owned by the current thread and that the current context is the one
-     * from this scene.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     */
-    protected void checkLock() {
-        ReentrantLock lock = Bridge.getLock();
-        if (!lock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
-        }
-        if (sCurrentContext != mContext) {
-            throw new IllegalStateException("Thread acquired a scene but is rendering a different one");
-        }
-    }
-
-    // VisibleForTesting
-    public static Configuration getConfiguration(RenderParams params) {
-        Configuration config = new Configuration();
-
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        ScreenSize screenSize = hardwareConfig.getScreenSize();
-        if (screenSize != null) {
-            switch (screenSize) {
-                case SMALL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_SMALL;
-                    break;
-                case NORMAL:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_NORMAL;
-                    break;
-                case LARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_LARGE;
-                    break;
-                case XLARGE:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_SIZE_XLARGE;
-                    break;
-            }
-        }
-
-        Density density = hardwareConfig.getDensity();
-        if (density == null) {
-            density = Density.MEDIUM;
-        }
-
-        config.screenWidthDp = hardwareConfig.getScreenWidth() / density.getDpiValue();
-        config.screenHeightDp = hardwareConfig.getScreenHeight() / density.getDpiValue();
-        if (config.screenHeightDp < config.screenWidthDp) {
-            //noinspection SuspiciousNameCombination
-            config.smallestScreenWidthDp = config.screenHeightDp;
-        } else {
-            config.smallestScreenWidthDp = config.screenWidthDp;
-        }
-        config.densityDpi = density.getDpiValue();
-
-        // never run in compat mode:
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-
-        ScreenOrientation orientation = hardwareConfig.getOrientation();
-        if (orientation != null) {
-            switch (orientation) {
-            case PORTRAIT:
-                config.orientation = Configuration.ORIENTATION_PORTRAIT;
-                break;
-            case LANDSCAPE:
-                config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-                break;
-            case SQUARE:
-                //noinspection deprecation
-                config.orientation = Configuration.ORIENTATION_SQUARE;
-                break;
-            }
-        } else {
-            config.orientation = Configuration.ORIENTATION_UNDEFINED;
-        }
-
-        ScreenRound roundness = hardwareConfig.getScreenRoundness();
-        if (roundness != null) {
-            switch (roundness) {
-                case ROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES;
-                    break;
-                case NOTROUND:
-                    config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_NO;
-            }
-        } else {
-            config.screenLayout |= Configuration.SCREENLAYOUT_ROUND_UNDEFINED;
-        }
-        String locale = params.getLocale();
-        if (locale != null && !locale.isEmpty()) config.locale = new Locale(locale);
-
-        // TODO: fill in more config info.
-
-        return config;
-    }
-
-
-    // --- FrameworkResourceIdProvider methods
-
-    @Override
-    public Integer getId(ResourceType resType, String resName) {
-        return Bridge.getResourceId(resType, resName);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
deleted file mode 100644
index d797eeca..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.view.AttachInfo_Accessor;
-import android.view.View.MeasureSpec;
-import android.widget.FrameLayout;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
- *
- * The class only provides a simple {@link #render()} method, but the full life-cycle of the
- * action must be respected.
- *
- * @see RenderAction
- *
- */
-public class RenderDrawable extends RenderAction<DrawableParams> {
-
-    public RenderDrawable(DrawableParams params) {
-        super(new DrawableParams(params));
-    }
-
-    public Result render() {
-        checkLock();
-        // get the drawable resource value
-        DrawableParams params = getParams();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-        ResourceValue drawableResource = params.getDrawable();
-
-        // resolve it
-        BridgeContext context = getContext();
-        drawableResource = context.getRenderResources().resolveResValue(drawableResource);
-
-        if (drawableResource == null) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        ResourceType resourceType = drawableResource.getResourceType();
-        if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
-            return Status.ERROR_NOT_A_DRAWABLE.createResult();
-        }
-
-        Drawable d = ResourceHelper.getDrawable(drawableResource, context);
-
-        final Boolean allStates =
-                params.getFlag(RenderParamsFlags.FLAG_KEY_RENDER_ALL_DRAWABLE_STATES);
-        if (allStates == Boolean.TRUE) {
-            final List<BufferedImage> result;
-
-            if (d instanceof StateListDrawable) {
-                result = new ArrayList<BufferedImage>();
-                final StateListDrawable stateList = (StateListDrawable) d;
-                for (int i = 0; i < stateList.getStateCount(); i++) {
-                    final Drawable stateDrawable = stateList.getStateDrawable(i);
-                    result.add(renderImage(hardwareConfig, stateDrawable, context));
-                }
-            } else {
-                result = Collections.singletonList(renderImage(hardwareConfig, d, context));
-            }
-
-            return Status.SUCCESS.createResult(result);
-        } else {
-            BufferedImage image = renderImage(hardwareConfig, d, context);
-            return Status.SUCCESS.createResult(image);
-        }
-    }
-
-    private BufferedImage renderImage(HardwareConfig hardwareConfig, Drawable d,
-            BridgeContext context) {
-        // create a simple FrameLayout
-        FrameLayout content = new FrameLayout(context);
-
-        // get the actual Drawable object to draw
-        content.setBackground(d);
-
-        // set the AttachInfo on the root view.
-        AttachInfo_Accessor.setAttachInfo(content);
-
-
-        // measure
-        int w = d.getIntrinsicWidth();
-        int h = d.getIntrinsicHeight();
-
-        final int screenWidth = hardwareConfig.getScreenWidth();
-        final int screenHeight = hardwareConfig.getScreenHeight();
-
-        if (w == -1 || h == -1) {
-            // Use screen size when either intrinsic width or height isn't available
-            w = screenWidth;
-            h = screenHeight;
-        } else if (w > screenWidth || h > screenHeight) {
-            // If image wouldn't fit to the screen, resize it to avoid cropping.
-
-            // We need to find scale such that scale * w <= screenWidth, scale * h <= screenHeight
-            double scale = Math.min((double) screenWidth / w, (double) screenHeight / h);
-
-            // scale * w / scale * h = w / h, so, proportions are preserved.
-            w = (int) Math.floor(scale * w);
-            h = (int) Math.floor(scale * h);
-        }
-
-        int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
-        int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
-        content.measure(w_spec, h_spec);
-
-        // now do the layout.
-        content.layout(0, 0, w, h);
-
-        // preDraw setup
-        AttachInfo_Accessor.dispatchOnPreDraw(content);
-
-        // draw into a new image
-        BufferedImage image = getImage(w, h);
-
-        // create an Android bitmap around the BufferedImage
-        Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
-                true /*isMutable*/, hardwareConfig.getDensity());
-
-        // create a Canvas around the Android bitmap
-        Canvas canvas = new Canvas(bitmap);
-        canvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-
-        // and draw
-        content.draw(canvas);
-        return image;
-    }
-
-    protected BufferedImage getImage(int w, int h) {
-        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
-        Graphics2D gc = image.createGraphics();
-        gc.setComposite(AlphaComposite.Src);
-
-        gc.setColor(new Color(0x00000000, true));
-        gc.fillRect(0, 0, w, h);
-
-        // done
-        gc.dispose();
-
-        return image;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
deleted file mode 100644
index d21955e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.IAnimationListener;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-import com.android.internal.view.menu.ActionMenuItemView;
-import com.android.internal.view.menu.BridgeMenuItemImpl;
-import com.android.internal.view.menu.IconMenuItemView;
-import com.android.internal.view.menu.ListMenuItemView;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuView;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.android.graphics.NopCanvas;
-import com.android.layoutlib.bridge.android.support.DesignLibUtil;
-import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
-import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
-import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.util.Pair;
-import com.android.util.PropertiesMap;
-
-import android.animation.AnimationThread;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Fragment_Delegate;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.os.Looper;
-import android.preference.Preference_Delegate;
-import android.view.AttachInfo_Accessor;
-import android.view.BridgeInflater;
-import android.view.Choreographer_Delegate;
-import android.view.IWindowManager;
-import android.view.IWindowManagerImpl;
-import android.view.Surface;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.view.ViewParent;
-import android.view.WindowManagerGlobal_Delegate;
-import android.widget.AbsListView;
-import android.widget.AbsSpinner;
-import android.widget.ActionMenuView;
-import android.widget.AdapterView;
-import android.widget.ExpandableListView;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.QuickContactBadge;
-import android.widget.TabHost;
-import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_ANIM_NOT_FOUND;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf;
-
-/**
- * Class implementing the render session.
- * <p/>
- * A session is a stateful representation of a layout file. It is initialized with data coming
- * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
- * be done on the layout.
- */
-public class RenderSessionImpl extends RenderAction<SessionParams> {
-
-    private static final Canvas NOP_CANVAS = new NopCanvas();
-
-    // scene state
-    private RenderSession mScene;
-    private BridgeXmlBlockParser mBlockParser;
-    private BridgeInflater mInflater;
-    private ViewGroup mViewRoot;
-    private FrameLayout mContentRoot;
-    private Canvas mCanvas;
-    private int mMeasuredScreenWidth = -1;
-    private int mMeasuredScreenHeight = -1;
-    private boolean mIsAlphaChannelImage;
-    /** If >= 0, a frame will be executed */
-    private long mElapsedFrameTimeNanos = -1;
-    /** True if one frame has been already executed to start the animations */
-    private boolean mFirstFrameExecuted = false;
-
-    // information being returned through the API
-    private BufferedImage mImage;
-    private List<ViewInfo> mViewInfoList;
-    private List<ViewInfo> mSystemViewInfoList;
-    private Layout.Builder mLayoutBuilder;
-    private boolean mNewRenderSize;
-
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        private PostInflateException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Creates a layout scene with all the information coming from the layout bridge API.
-     * <p>
-     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init(long)},
-     * which act as a
-     * call to {@link RenderSessionImpl#acquire(long)}
-     *
-     * @see Bridge#createSession(SessionParams)
-     */
-    public RenderSessionImpl(SessionParams params) {
-        super(new SessionParams(params));
-    }
-
-    /**
-     * Initializes and acquires the scene, creating various Android objects such as context,
-     * inflater, and parser.
-     *
-     * @param timeout the time to wait if another rendering is happening.
-     *
-     * @return whether the scene was prepared
-     *
-     * @see #acquire(long)
-     * @see #release()
-     */
-    @Override
-    public Result init(long timeout) {
-        Result result = super.init(timeout);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        SessionParams params = getParams();
-        BridgeContext context = getContext();
-
-        // use default of true in case it's not found to use alpha by default
-        mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(),
-                "windowIsFloating", true, true);
-
-        mLayoutBuilder = new Layout.Builder(params, context);
-
-        // FIXME: find those out, and possibly add them to the render params
-        boolean hasNavigationBar = true;
-        //noinspection ConstantConditions
-        IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
-                context.getMetrics(), Surface.ROTATION_0, hasNavigationBar);
-        WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
-
-        // build the inflater and parser.
-        mInflater = new BridgeInflater(context, params.getLayoutlibCallback());
-        context.setBridgeInflater(mInflater);
-
-        mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Measures the the current layout if needed (see {@link #invalidateRenderingSize}).
-     */
-    private void measureLayout(@NonNull SessionParams params) {
-        // only do the screen measure when needed.
-        if (mMeasuredScreenWidth != -1) {
-            return;
-        }
-
-        RenderingMode renderingMode = params.getRenderingMode();
-        HardwareConfig hardwareConfig = params.getHardwareConfig();
-
-        mNewRenderSize = true;
-        mMeasuredScreenWidth = hardwareConfig.getScreenWidth();
-        mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
-
-        if (renderingMode != RenderingMode.NORMAL) {
-            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
-                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
-                    : MeasureSpec.EXACTLY;
-
-            // We used to compare the measured size of the content to the screen size but
-            // this does not work anymore due to the 2 following issues:
-            // - If the content is in a decor (system bar, title/action bar), the root view
-            //   will not resize even with the UNSPECIFIED because of the embedded layout.
-            // - If there is no decor, but a dialog frame, then the dialog padding prevents
-            //   comparing the size of the content to the screen frame (as it would not
-            //   take into account the dialog padding).
-
-            // The solution is to first get the content size in a normal rendering, inside
-            // the decor or the dialog padding.
-            // Then measure only the content with UNSPECIFIED to see the size difference
-            // and apply this to the screen size.
-
-            View measuredView = mContentRoot.getChildAt(0);
-
-            // first measure the full layout, with EXACTLY to get the size of the
-            // content as it is inside the decor/dialog
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> exactMeasure = measureView(
-                    mViewRoot, measuredView,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-
-            // now measure the content only using UNSPECIFIED (where applicable, based on
-            // the rendering mode). This will give us the size the content needs.
-            @SuppressWarnings("deprecation")
-            Pair<Integer, Integer> result = measureView(
-                    mContentRoot, mContentRoot.getChildAt(0),
-                    mMeasuredScreenWidth, widthMeasureSpecMode,
-                    mMeasuredScreenHeight, heightMeasureSpecMode);
-
-            // If measuredView is not null, exactMeasure nor result will be null.
-            assert exactMeasure != null;
-            assert result != null;
-
-            // now look at the difference and add what is needed.
-            if (renderingMode.isHorizExpand()) {
-                int measuredWidth = exactMeasure.getFirst();
-                int neededWidth = result.getFirst();
-                if (neededWidth > measuredWidth) {
-                    mMeasuredScreenWidth += neededWidth - measuredWidth;
-                }
-                if (mMeasuredScreenWidth < measuredWidth) {
-                    // If the screen width is less than the exact measured width,
-                    // expand to match.
-                    mMeasuredScreenWidth = measuredWidth;
-                }
-            }
-
-            if (renderingMode.isVertExpand()) {
-                int measuredHeight = exactMeasure.getSecond();
-                int neededHeight = result.getSecond();
-                if (neededHeight > measuredHeight) {
-                    mMeasuredScreenHeight += neededHeight - measuredHeight;
-                }
-                if (mMeasuredScreenHeight < measuredHeight) {
-                    // If the screen height is less than the exact measured height,
-                    // expand to match.
-                    mMeasuredScreenHeight = measuredHeight;
-                }
-            }
-        }
-    }
-
-    /**
-     * Inflates the layout.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #init(long)} was not called.
-     */
-    public Result inflate() {
-        checkLock();
-
-        try {
-            mViewRoot = new Layout(mLayoutBuilder);
-            mLayoutBuilder = null;  // Done with the builder.
-            mContentRoot = ((Layout) mViewRoot).getContentRoot();
-            SessionParams params = getParams();
-            BridgeContext context = getContext();
-
-            if (Bridge.isLocaleRtl(params.getLocale())) {
-                if (!params.isRtlSupported()) {
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED,
-                            "You are using a right-to-left " +
-                                    "(RTL) locale but RTL is not enabled", null);
-                } else if (params.getSimulatedPlatformVersion() < 17) {
-                    // This will render ok because we are using the latest layoutlib but at least
-                    // warn the user that this might fail in a real device.
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
-                            "right-to-left " +
-                            "(RTL) locale but RTL is not supported for API level < 17", null);
-                }
-            }
-
-            // Sets the project callback (custom view loader) to the fragment delegate so that
-            // it can instantiate the custom Fragment.
-            Fragment_Delegate.setLayoutlibCallback(params.getLayoutlibCallback());
-
-            String rootTag = params.getFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG);
-            boolean isPreference = "PreferenceScreen".equals(rootTag);
-            View view;
-            if (isPreference) {
-                // First try to use the support library inflater. If something fails, fallback
-                // to the system preference inflater.
-                view = SupportPreferencesUtil.inflatePreference(getContext(), mBlockParser,
-                        mContentRoot);
-                if (view == null) {
-                    view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
-                            mContentRoot);
-                }
-            } else {
-                view = mInflater.inflate(mBlockParser, mContentRoot);
-            }
-
-            // done with the parser, pop it.
-            context.popParser();
-
-            Fragment_Delegate.setLayoutlibCallback(null);
-
-            // set the AttachInfo on the root view.
-            AttachInfo_Accessor.setAttachInfo(mViewRoot);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
-            mInflater.onDoneInflation();
-
-            setActiveToolbar(view, context, params);
-
-            measureLayout(params);
-            measureView(mViewRoot, null /*measuredView*/,
-                    mMeasuredScreenWidth, MeasureSpec.EXACTLY,
-                    mMeasuredScreenHeight, MeasureSpec.EXACTLY);
-            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            return SUCCESS.createResult();
-        } catch (PostInflateException e) {
-            return ERROR_INFLATION.createResult(e.getMessage(), e);
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_INFLATION.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Sets the time for which the next frame will be selected. The time is the elapsed time from
-     * the current system nanos time. You
-     */
-    public void setElapsedFrameTimeNanos(long nanos) {
-        mElapsedFrameTimeNanos = nanos;
-    }
-
-    /**
-     * Runs a layout pass for the given view root
-     */
-    private static void doLayout(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot,
-            int width, int height) {
-        // measure again with the size we need
-        // This must always be done before the call to layout
-        measureView(viewRoot, null /*measuredView*/,
-                width, MeasureSpec.EXACTLY,
-                height, MeasureSpec.EXACTLY);
-
-        // now do the layout.
-        viewRoot.layout(0, 0, width, height);
-        handleScrolling(context, viewRoot);
-    }
-
-    /**
-     * Renders the given view hierarchy to the passed canvas and returns the result of the render
-     * operation.
-     * @param canvas an optional canvas to render the views to. If null, only the measure and
-     * layout steps will be executed.
-     */
-    private static Result renderAndBuildResult(@NonNull ViewGroup viewRoot, @Nullable Canvas canvas) {
-        if (canvas == null) {
-            return SUCCESS.createResult();
-        }
-
-        AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
-        viewRoot.draw(canvas);
-
-        return SUCCESS.createResult();
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result render(boolean freshRender) {
-        return renderAndBuildResult(freshRender, false);
-    }
-
-    /**
-     * Measures the layout
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    public Result measure() {
-        return renderAndBuildResult(false, true);
-    }
-
-    /**
-     * Renders the scene.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
-     *      the case where bitmaps are reused). This is typically needed when not playing
-     *      animations.)
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see SessionParams#getRenderingMode()
-     * @see RenderSession#render(long)
-     */
-    private Result renderAndBuildResult(boolean freshRender, boolean onlyMeasure) {
-        checkLock();
-
-        SessionParams params = getParams();
-
-        try {
-            if (mViewRoot == null) {
-                return ERROR_NOT_INFLATED.createResult();
-            }
-
-            measureLayout(params);
-
-            HardwareConfig hardwareConfig = params.getHardwareConfig();
-            Result renderResult = SUCCESS.createResult();
-            if (onlyMeasure) {
-                // delete the canvas and image to reset them on the next full rendering
-                mImage = null;
-                mCanvas = null;
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-            } else {
-                // draw the views
-                // create the BufferedImage into which the layout will be rendered.
-                boolean newImage = false;
-
-                // When disableBitmapCaching is true, we do not reuse mImage and
-                // we create a new one in every render.
-                // This is useful when mImage is just a wrapper of Graphics2D so
-                // it doesn't get cached.
-                boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
-                    RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
-                if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
-                    mNewRenderSize = false;
-                    if (params.getImageFactory() != null) {
-                        mImage = params.getImageFactory().getImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight);
-                    } else {
-                        mImage = new BufferedImage(
-                                mMeasuredScreenWidth,
-                                mMeasuredScreenHeight,
-                                BufferedImage.TYPE_INT_ARGB);
-                        newImage = true;
-                    }
-
-                    if (params.isBgColorOverridden()) {
-                        // since we override the content, it's the same as if it was a new image.
-                        newImage = true;
-                        Graphics2D gc = mImage.createGraphics();
-                        gc.setColor(new Color(params.getOverrideBgColor(), true));
-                        gc.setComposite(AlphaComposite.Src);
-                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                        gc.dispose();
-                    }
-
-                    // create an Android bitmap around the BufferedImage
-                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
-                            true /*isMutable*/, hardwareConfig.getDensity());
-
-                    if (mCanvas == null) {
-                        // create a Canvas around the Android bitmap
-                        mCanvas = new Canvas(bitmap);
-                    } else {
-                        mCanvas.setBitmap(bitmap);
-                    }
-                    mCanvas.setDensity(hardwareConfig.getDensity().getDpiValue());
-                }
-
-                if (freshRender && !newImage) {
-                    Graphics2D gc = mImage.createGraphics();
-                    gc.setComposite(AlphaComposite.Src);
-
-                    gc.setColor(new Color(0x00000000, true));
-                    gc.fillRect(0, 0,
-                            mMeasuredScreenWidth, mMeasuredScreenHeight);
-
-                    // done
-                    gc.dispose();
-                }
-
-                doLayout(getContext(), mViewRoot, mMeasuredScreenWidth, mMeasuredScreenHeight);
-                if (mElapsedFrameTimeNanos >= 0) {
-                    long initialTime = System_Delegate.nanoTime();
-                    if (!mFirstFrameExecuted) {
-                        // We need to run an initial draw call to initialize the animations
-                        renderAndBuildResult(mViewRoot, NOP_CANVAS);
-
-                        // The first frame will initialize the animations
-                        Choreographer_Delegate.doFrame(initialTime);
-                        mFirstFrameExecuted = true;
-                    }
-                    // Second frame will move the animations
-                    Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos);
-                }
-                renderResult = renderAndBuildResult(mViewRoot, mCanvas);
-            }
-
-            mSystemViewInfoList =
-                    visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
-                    false);
-
-            // success!
-            return renderResult;
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-        }
-    }
-
-    /**
-     * Executes {@link View#measure(int, int)} on a given view with the given parameters (used
-     * to create measure specs with {@link MeasureSpec#makeMeasureSpec(int, int)}.
-     *
-     * if <var>measuredView</var> is non null, the method returns a {@link Pair} of (width, height)
-     * for the view (using {@link View#getMeasuredWidth()} and {@link View#getMeasuredHeight()}).
-     *
-     * @param viewToMeasure the view on which to execute measure().
-     * @param measuredView if non null, the view to query for its measured width/height.
-     * @param width the width to use in the MeasureSpec.
-     * @param widthMode the MeasureSpec mode to use for the width.
-     * @param height the height to use in the MeasureSpec.
-     * @param heightMode the MeasureSpec mode to use for the height.
-     * @return the measured width/height if measuredView is non-null, null otherwise.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
-            int width, int widthMode, int height, int heightMode) {
-        int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
-        int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode);
-        viewToMeasure.measure(w_spec, h_spec);
-
-        if (measuredView != null) {
-            return Pair.of(measuredView.getMeasuredWidth(), measuredView.getMeasuredHeight());
-        }
-
-        return null;
-    }
-
-    /**
-     * Animate an object
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#animate(Object, String, boolean, IAnimationListener)
-     */
-    public Result animate(Object targetObject, String animationName,
-            boolean isFrameworkAnimation, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // find the animation file.
-        ResourceValue animationResource;
-        int animationId = 0;
-        if (isFrameworkAnimation) {
-            animationResource = context.getRenderResources().getFrameworkResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName);
-            }
-        } else {
-            animationResource = context.getRenderResources().getProjectResource(
-                    ResourceType.ANIMATOR, animationName);
-            if (animationResource != null) {
-                animationId = context.getLayoutlibCallback().getResourceId(
-                        ResourceType.ANIMATOR, animationName);
-            }
-        }
-
-        if (animationResource != null) {
-            try {
-                Animator anim = AnimatorInflater.loadAnimator(context, animationId);
-                if (anim != null) {
-                    anim.setTarget(targetObject);
-
-                    new PlayAnimationThread(anim, this, animationName, listener).start();
-
-                    return SUCCESS.createResult();
-                }
-            } catch (Exception e) {
-                // get the real cause of the exception.
-                Throwable t = e;
-                while (t.getCause() != null) {
-                    t = t.getCause();
-                }
-
-                return ERROR_UNKNOWN.createResult(t.getMessage(), t);
-            }
-        }
-
-        return ERROR_ANIM_NOT_FOUND.createResult();
-    }
-
-    /**
-     * Insert a new child into an existing parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
-     */
-    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
-            final int index, IAnimationListener listener) {
-        checkLock();
-
-        BridgeContext context = getContext();
-
-        // create a block parser for the XML
-        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                childXml, context, false /* platformResourceFlag */);
-
-        // inflate the child without adding it to the root since we want to control where it'll
-        // get added. We do pass the parentView however to ensure that the layoutParams will
-        // be created correctly.
-        final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
-        blockParser.ensurePopped();
-
-        invalidateRenderingSize();
-
-        if (listener != null) {
-            new AnimationThread(this, "insertChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parentView.setLayoutTransition(new LayoutTransition());
-                    return addView(parentView, child, index);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parentView.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(child);
-        }
-
-        // add it to the parentView in the correct location
-        Result result = addView(parentView, child, index);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (result.isSuccess()) {
-            result = result.getCopyWithData(child);
-        }
-
-        return result;
-    }
-
-    /**
-     * Adds a given view to a given parent at a given index.
-     *
-     * @param parent the parent to receive the view
-     * @param view the view to add to the parent
-     * @param index the index where to do the add.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result addView(ViewGroup parent, View view, int index) {
-        try {
-            parent.addView(view, index);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Moves a view to a new parent at a given location
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
-     */
-    public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
-            Map<String, String> layoutParamsMap, final IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        LayoutParams layoutParams = null;
-        if (layoutParamsMap != null) {
-            // need to create a new LayoutParams object for the new parent.
-            layoutParams = newParentView.generateLayoutParams(
-                    new BridgeLayoutParamsMapAttributes(layoutParamsMap));
-        }
-
-        // get the current parent of the view that needs to be moved.
-        final ViewGroup previousParent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            final LayoutParams params = layoutParams;
-
-            // there is no support for animating views across layouts, so in case the new and old
-            // parent views are different we fake the animation through a no animation thread.
-            if (previousParent != newParentView) {
-                new Thread("not animated moveChild") {
-                    @Override
-                    public void run() {
-                        Result result = moveView(previousParent, newParentView, childView, index,
-                                params);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                        }
-
-                        // ready to do the work, acquire the scene.
-                        result = acquire(250);
-                        if (!result.isSuccess()) {
-                            listener.done(result);
-                            return;
-                        }
-
-                        try {
-                            result = render(false /*freshRender*/);
-                            if (result.isSuccess()) {
-                                listener.onNewFrame(RenderSessionImpl.this.getSession());
-                            }
-                        } finally {
-                            release();
-                        }
-
-                        listener.done(result);
-                    }
-                }.start();
-            } else {
-                new AnimationThread(this, "moveChild", listener) {
-
-                    @Override
-                    public Result preAnimation() {
-                        // set up the transition for the parent.
-                        LayoutTransition transition = new LayoutTransition();
-                        previousParent.setLayoutTransition(transition);
-
-                        // tweak the animation durations and start delays (to match the duration of
-                        // animation playing just before).
-                        // Note: Cannot user Animation.setDuration() directly. Have to set it
-                        // on the LayoutTransition.
-                        transition.setDuration(LayoutTransition.DISAPPEARING, 100);
-                        // CHANGE_DISAPPEARING plays after DISAPPEARING
-                        transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.CHANGE_APPEARING, 100);
-                        // CHANGE_APPEARING plays after CHANGE_APPEARING
-                        transition.setStartDelay(LayoutTransition.APPEARING, 100);
-
-                        transition.setDuration(LayoutTransition.APPEARING, 100);
-
-                        return moveView(previousParent, newParentView, childView, index, params);
-                    }
-
-                    @Override
-                    public void postAnimation() {
-                        previousParent.setLayoutTransition(null);
-                        newParentView.setLayoutTransition(null);
-                    }
-                }.start();
-            }
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult(layoutParams);
-        }
-
-        Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        result = render(false /*freshRender*/);
-        if (layoutParams != null && result.isSuccess()) {
-            result = result.getCopyWithData(layoutParams);
-        }
-
-        return result;
-    }
-
-    /**
-     * Moves a View from its current parent to a new given parent at a new given location, with
-     * an optional new {@link LayoutParams} instance
-     *
-     * @param previousParent the previous parent, still owning the child at the time of the call.
-     * @param newParent the new parent
-     * @param movedView the view to move
-     * @param index the new location in the new parent
-     * @param params an option (can be null) {@link LayoutParams} instance.
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result moveView(ViewGroup previousParent, final ViewGroup newParent,
-            final View movedView, final int index, final LayoutParams params) {
-        try {
-            // check if there is a transition on the previousParent.
-            LayoutTransition previousTransition = previousParent.getLayoutTransition();
-            if (previousTransition != null) {
-                // in this case there is an animation. This means we have to wait for the child's
-                // parent reference to be null'ed out so that we can add it to the new parent.
-                // It is technically removed right before the DISAPPEARING animation is done (if
-                // the animation of this type is not null, otherwise it's after which is impossible
-                // to handle).
-                // Because there is no move animation, if the new parent is the same as the old
-                // parent, we need to wait until the CHANGE_DISAPPEARING animation is done before
-                // adding the child or the child will appear in its new location before the
-                // other children have made room for it.
-
-                // add a listener to the transition to be notified of the actual removal.
-                previousTransition.addTransitionListener(new TransitionListener() {
-                    private int mChangeDisappearingCount = 0;
-
-                    @Override
-                    public void startTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount++;
-                        }
-                    }
-
-                    @Override
-                    public void endTransition(LayoutTransition transition, ViewGroup container,
-                            View view, int transitionType) {
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING) {
-                            mChangeDisappearingCount--;
-                        }
-
-                        if (transitionType == LayoutTransition.CHANGE_DISAPPEARING &&
-                                mChangeDisappearingCount == 0) {
-                            // add it to the parentView in the correct location
-                            if (params != null) {
-                                newParent.addView(movedView, index, params);
-                            } else {
-                                newParent.addView(movedView, index);
-                            }
-                        }
-                    }
-                });
-
-                // remove the view from the current parent.
-                previousParent.removeView(movedView);
-
-                // and return since adding the view to the new parent is done in the listener.
-                return SUCCESS.createResult();
-            } else {
-                // standard code with no animation. pretty simple.
-                previousParent.removeView(movedView);
-
-                // add it to the parentView in the correct location
-                if (params != null) {
-                    newParent.addView(movedView, index, params);
-                } else {
-                    newParent.addView(movedView, index);
-                }
-
-                return SUCCESS.createResult();
-            }
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Removes a child from its current parent.
-     * <p>
-     * {@link #acquire(long)} must have been called before this.
-     *
-     * @throws IllegalStateException if the current context is different than the one owned by
-     *      the scene, or if {@link #acquire(long)} was not called.
-     *
-     * @see RenderSession#removeChild(Object, IAnimationListener)
-     */
-    public Result removeChild(final View childView, IAnimationListener listener) {
-        checkLock();
-
-        invalidateRenderingSize();
-
-        final ViewGroup parent = (ViewGroup) childView.getParent();
-
-        if (listener != null) {
-            new AnimationThread(this, "moveChild", listener) {
-
-                @Override
-                public Result preAnimation() {
-                    parent.setLayoutTransition(new LayoutTransition());
-                    return removeView(parent, childView);
-                }
-
-                @Override
-                public void postAnimation() {
-                    parent.setLayoutTransition(null);
-                }
-            }.start();
-
-            // always return success since the real status will come through the listener.
-            return SUCCESS.createResult();
-        }
-
-        Result result = removeView(parent, childView);
-        if (!result.isSuccess()) {
-            return result;
-        }
-
-        return render(false /*freshRender*/);
-    }
-
-    /**
-     * Removes a given view from its current parent.
-     *
-     * @param view the view to remove from its parent
-     *
-     * @return a Result with {@link Status#SUCCESS} or
-     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
-     *     adding views.
-     */
-    private Result removeView(ViewGroup parent, View view) {
-        try {
-            parent.removeView(view);
-            return SUCCESS.createResult();
-        } catch (UnsupportedOperationException e) {
-            // looks like this is a view class that doesn't support children manipulation!
-            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
-        }
-    }
-
-    /**
-     * Post process on a view hierarchy that was just inflated.
-     * <p/>
-     * At the moment this only supports TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param layoutlibCallback callback to the project.
-     * @param skip the view and it's children are not processed.
-     */
-    @SuppressWarnings("deprecation")  // For the use of Pair
-    private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
-            throws PostInflateException {
-        if (view == skip) {
-            return;
-        }
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost) view, layoutlibCallback);
-        } else if (view instanceof QuickContactBadge) {
-            QuickContactBadge badge = (QuickContactBadge) view;
-            badge.setImageToDefault();
-        } else if (view instanceof AdapterView<?>) {
-            // get the view ID.
-            int id = view.getId();
-
-            BridgeContext context = getContext();
-
-            // get a ResourceReference from the integer ID.
-            ResourceReference listRef = context.resolveId(id);
-
-            if (listRef != null) {
-                SessionParams params = getParams();
-                AdapterBinding binding = params.getAdapterBindings().get(listRef);
-
-                // if there was no adapter binding, trying to get it from the call back.
-                if (binding == null) {
-                    binding = layoutlibCallback.getAdapterBinding(
-                            listRef, context.getViewKey(view), view);
-                }
-
-                if (binding != null) {
-
-                    if (view instanceof AbsListView) {
-                        if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
-                                view instanceof ListView) {
-                            ListView list = (ListView) view;
-
-                            boolean skipCallbackParser = false;
-
-                            int count = binding.getHeaderCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getHeaderAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addHeaderView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-
-                            count = binding.getFooterCount();
-                            for (int i = 0; i < count; i++) {
-                                Pair<View, Boolean> pair = context.inflateView(
-                                        binding.getFooterAt(i),
-                                        list, false, skipCallbackParser);
-                                if (pair.getFirst() != null) {
-                                    list.addFooterView(pair.getFirst());
-                                }
-
-                                skipCallbackParser |= pair.getSecond();
-                            }
-                        }
-
-                        if (view instanceof ExpandableListView) {
-                            ((ExpandableListView) view).setAdapter(
-                                    new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
-                        } else {
-                            ((AbsListView) view).setAdapter(
-                                    new FakeAdapter(listRef, binding, layoutlibCallback));
-                        }
-                    } else if (view instanceof AbsSpinner) {
-                        ((AbsSpinner) view).setAdapter(
-                                new FakeAdapter(listRef, binding, layoutlibCallback));
-                    }
-                }
-            }
-        } else if (view instanceof ViewGroup) {
-            mInflater.postInflateProcess(view);
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int c = 0; c < count; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, layoutlibCallback, skip);
-            }
-        }
-    }
-
-    /**
-     * If the root layout is a CoordinatorLayout with an AppBar:
-     * Set the title of the AppBar to the title of the activity context.
-     */
-    private void setActiveToolbar(View view, BridgeContext context, SessionParams params) {
-        View coordinatorLayout = findChildView(view, DesignLibUtil.CN_COORDINATOR_LAYOUT);
-        if (coordinatorLayout == null) {
-            return;
-        }
-        View appBar = findChildView(coordinatorLayout, DesignLibUtil.CN_APPBAR_LAYOUT);
-        if (appBar == null) {
-            return;
-        }
-        ViewGroup collapsingToolbar =
-                (ViewGroup) findChildView(appBar, DesignLibUtil.CN_COLLAPSING_TOOLBAR_LAYOUT);
-        if (collapsingToolbar == null) {
-            return;
-        }
-        if (!hasToolbar(collapsingToolbar)) {
-            return;
-        }
-        RenderResources res = context.getRenderResources();
-        String title = params.getAppLabel();
-        ResourceValue titleValue = res.findResValue(title, false);
-        if (titleValue != null && titleValue.getValue() != null) {
-            title = titleValue.getValue();
-        }
-        DesignLibUtil.setTitle(collapsingToolbar, title);
-    }
-
-    private View findChildView(View view, String className) {
-        if (!(view instanceof ViewGroup)) {
-            return null;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), className)) {
-                return group.getChildAt(i);
-            }
-        }
-        return null;
-    }
-
-    private boolean hasToolbar(View collapsingToolbar) {
-        if (!(collapsingToolbar instanceof ViewGroup)) {
-            return false;
-        }
-        ViewGroup group = (ViewGroup) collapsingToolbar;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            if (isInstanceOf(group.getChildAt(i), DesignLibUtil.CN_TOOLBAR)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If
-     * the component supports nested scrolling attempt that first, then use the unconsumed scroll
-     * part to scroll the content in the component.
-     */
-    private static void handleScrolling(BridgeContext context, View view) {
-        int scrollPosX = context.getScrollXPos(view);
-        int scrollPosY = context.getScrollYPos(view);
-        if (scrollPosX != 0 || scrollPosY != 0) {
-            if (view.isNestedScrollingEnabled()) {
-                int[] consumed = new int[2];
-                int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0;
-                axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0;
-                if (view.startNestedScroll(axis)) {
-                    view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null);
-                    view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY,
-                            null);
-                    view.stopNestedScroll();
-                    scrollPosX -= consumed[0];
-                    scrollPosY -= consumed[1];
-                }
-            }
-            if (scrollPosX != 0 || scrollPosY != 0) {
-                view.scrollTo(scrollPosX, scrollPosY);
-            }
-        }
-
-        if (!(view instanceof ViewGroup)) {
-            return;
-        }
-        ViewGroup group = (ViewGroup) view;
-        for (int i = 0; i < group.getChildCount(); i++) {
-            View child = group.getChildAt(i);
-            handleScrolling(context, child);
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param layoutlibCallback The project callback object to access the project R class.
-     * @throws PostInflateException if TabHost is missing the required ids for TabHost
-     */
-    private void setupTabHost(TabHost tabHost, LayoutlibCallback layoutlibCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if (!(v instanceof TabWidget)) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the frameLayout is empty)
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if (!(v instanceof FrameLayout)) {
-            //noinspection SpellCheckingInspection
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the frameLayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        if (count == 0) {
-            // Create a dummy child to get a single tab
-            TabSpec spec = tabHost.newTabSpec("tag")
-                    .setIndicator("Tab Label", tabHost.getResources()
-                            .getDrawable(android.R.drawable.ic_menu_info_details, null))
-                    .setContent(tag -> new LinearLayout(getContext()));
-            tabHost.addTab(spec);
-        } else {
-            // for each child of the frameLayout, add a new TabSpec
-            for (int i = 0 ; i < count ; i++) {
-                View child = content.getChildAt(i);
-                String tabSpec = String.format("tab_spec%d", i+1);
-                @SuppressWarnings("ConstantConditions")  // child cannot be null.
-                int id = child.getId();
-                @SuppressWarnings("deprecation")
-                Pair<ResourceType, String> resource = layoutlibCallback.resolveResourceId(id);
-                String name;
-                if (resource != null) {
-                    name = resource.getSecond();
-                } else {
-                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
-                }
-                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-            }
-        }
-    }
-
-    /**
-     * Visits a {@link View} and its children and generate a {@link ViewInfo} containing the
-     * bounds of all the views.
-     *
-     * @param view the root View
-     * @param hOffset horizontal offset for the view bounds.
-     * @param vOffset vertical offset for the view bounds.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame.
-     *
-     * @return {@code ViewInfo} containing the bounds of the view and it children otherwise.
-     */
-    private ViewInfo visit(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        ViewInfo result = createViewInfo(view, hOffset, vOffset, setExtendedInfo, isContentFrame);
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            result.setChildren(visitAllChildren(group, isContentFrame ? 0 : hOffset,
-                    isContentFrame ? 0 : vOffset,
-                    setExtendedInfo, isContentFrame));
-        }
-        return result;
-    }
-
-    /**
-     * Visits all the children of a given ViewGroup and generates a list of {@link ViewInfo}
-     * containing the bounds of all the views. It also initializes the {@link #mViewInfoList} with
-     * the children of the {@code mContentRoot}.
-     *
-     * @param viewGroup the root View
-     * @param hOffset horizontal offset from the top for the content view frame.
-     * @param vOffset vertical offset from the top for the content view frame.
-     * @param setExtendedInfo whether to set the extended view info in the {@link ViewInfo} object.
-     * @param isContentFrame {@code true} if the {@code ViewInfo} to be created is part of the
-     *                       content frame. {@code false} if the {@code ViewInfo} to be created is
-     *                       part of the system decor.
-     */
-    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int hOffset, int vOffset,
-            boolean setExtendedInfo, boolean isContentFrame) {
-        if (viewGroup == null) {
-            return null;
-        }
-
-        if (!isContentFrame) {
-            vOffset += viewGroup.getTop();
-            hOffset += viewGroup.getLeft();
-        }
-
-        int childCount = viewGroup.getChildCount();
-        if (viewGroup == mContentRoot) {
-            List<ViewInfo> childrenWithoutOffset = new ArrayList<>(childCount);
-            List<ViewInfo> childrenWithOffset = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                ViewInfo[] childViewInfo =
-                        visitContentRoot(viewGroup.getChildAt(i), hOffset, vOffset,
-                        setExtendedInfo);
-                childrenWithoutOffset.add(childViewInfo[0]);
-                childrenWithOffset.add(childViewInfo[1]);
-            }
-            mViewInfoList = childrenWithOffset;
-            return childrenWithoutOffset;
-        } else {
-            List<ViewInfo> children = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                children.add(visit(viewGroup.getChildAt(i), hOffset, vOffset, setExtendedInfo,
-                        isContentFrame));
-            }
-            return children;
-        }
-    }
-
-    /**
-     * Visits the children of {@link #mContentRoot} and generates {@link ViewInfo} containing the
-     * bounds of all the views. It returns two {@code ViewInfo} objects with the same children,
-     * one with the {@code offset} and other without the {@code offset}. The offset is needed to
-     * get the right bounds if the {@code ViewInfo} hierarchy is accessed from
-     * {@code mViewInfoList}. When the hierarchy is accessed via {@code mSystemViewInfoList}, the
-     * offset is not needed.
-     *
-     * @return an array of length two, with ViewInfo at index 0 is without offset and ViewInfo at
-     *         index 1 is with the offset.
-     */
-    @NonNull
-    private ViewInfo[] visitContentRoot(View view, int hOffset, int vOffset,
-            boolean setExtendedInfo) {
-        ViewInfo[] result = new ViewInfo[2];
-        if (view == null) {
-            return result;
-        }
-
-        result[0] = createViewInfo(view, 0, 0, setExtendedInfo, true);
-        result[1] = createViewInfo(view, hOffset, vOffset, setExtendedInfo, true);
-        if (view instanceof ViewGroup) {
-            List<ViewInfo> children =
-                    visitAllChildren((ViewGroup) view, 0, 0, setExtendedInfo, true);
-            result[0].setChildren(children);
-            result[1].setChildren(children);
-        }
-        return result;
-    }
-
-    /**
-     * Creates a {@link ViewInfo} for the view. The {@code ViewInfo} corresponding to the children
-     * of the {@code view} are not created. Consequently, the children of {@code ViewInfo} is not
-     * set.
-     * @param hOffset horizontal offset for the view bounds. Used only if view is part of the
-     * content frame.
-     * @param vOffset vertial an offset for the view bounds. Used only if view is part of the
-     * content frame.
-     */
-    private ViewInfo createViewInfo(View view, int hOffset, int vOffset, boolean setExtendedInfo,
-            boolean isContentFrame) {
-        if (view == null) {
-            return null;
-        }
-
-        ViewParent parent = view.getParent();
-        ViewInfo result;
-        if (isContentFrame) {
-            // Account for parent scroll values when calculating the bounding box
-            int scrollX = parent != null ? ((View)parent).getScrollX() : 0;
-            int scrollY = parent != null ? ((View)parent).getScrollY() : 0;
-
-            // The view is part of the layout added by the user. Hence,
-            // the ViewCookie may be obtained only through the Context.
-            result = new ViewInfo(view.getClass().getName(),
-                    getContext().getViewKey(view), -scrollX + view.getLeft() + hOffset,
-                    -scrollY + view.getTop() + vOffset, -scrollX + view.getRight() + hOffset,
-                    -scrollY + view.getBottom() + vOffset,
-                    view, view.getLayoutParams());
-        } else {
-            // We are part of the system decor.
-            SystemViewInfo r = new SystemViewInfo(view.getClass().getName(),
-                    getViewKey(view),
-                    view.getLeft(), view.getTop(), view.getRight(),
-                    view.getBottom(), view, view.getLayoutParams());
-            result = r;
-            // We currently mark three kinds of views:
-            // 1. Menus in the Action Bar
-            // 2. Menus in the Overflow popup.
-            // 3. The overflow popup button.
-            if (view instanceof ListMenuItemView) {
-                // Mark 2.
-                // All menus in the popup are of type ListMenuItemView.
-                r.setViewType(ViewType.ACTION_BAR_OVERFLOW_MENU);
-            } else {
-                // Mark 3.
-                ViewGroup.LayoutParams lp = view.getLayoutParams();
-                if (lp instanceof ActionMenuView.LayoutParams &&
-                        ((ActionMenuView.LayoutParams) lp).isOverflowButton) {
-                    r.setViewType(ViewType.ACTION_BAR_OVERFLOW);
-                } else {
-                    // Mark 1.
-                    // A view is a menu in the Action Bar is it is not the overflow button and of
-                    // its parent is of type ActionMenuView. We can also check if the view is
-                    // instanceof ActionMenuItemView but that will fail for menus using
-                    // actionProviderClass.
-                    while (parent != mViewRoot && parent instanceof ViewGroup) {
-                        if (parent instanceof ActionMenuView) {
-                            r.setViewType(ViewType.ACTION_BAR_MENU);
-                            break;
-                        }
-                        parent = parent.getParent();
-                    }
-                }
-            }
-        }
-
-        if (setExtendedInfo) {
-            MarginLayoutParams marginParams = null;
-            LayoutParams params = view.getLayoutParams();
-            if (params instanceof MarginLayoutParams) {
-                marginParams = (MarginLayoutParams) params;
-            }
-            result.setExtendedInfo(view.getBaseline(),
-                    marginParams != null ? marginParams.leftMargin : 0,
-                    marginParams != null ? marginParams.topMargin : 0,
-                    marginParams != null ? marginParams.rightMargin : 0,
-                    marginParams != null ? marginParams.bottomMargin : 0);
-        }
-
-        return result;
-    }
-
-    /* (non-Javadoc)
-     * The cookie for menu items are stored in menu item and not in the map from View stored in
-     * BridgeContext.
-     */
-    @Nullable
-    private Object getViewKey(View view) {
-        BridgeContext context = getContext();
-        if (!(view instanceof MenuView.ItemView)) {
-            return context.getViewKey(view);
-        }
-        MenuItemImpl menuItem;
-        if (view instanceof ActionMenuItemView) {
-            menuItem = ((ActionMenuItemView) view).getItemData();
-        } else if (view instanceof ListMenuItemView) {
-            menuItem = ((ListMenuItemView) view).getItemData();
-        } else if (view instanceof IconMenuItemView) {
-            menuItem = ((IconMenuItemView) view).getItemData();
-        } else {
-            menuItem = null;
-        }
-        if (menuItem instanceof BridgeMenuItemImpl) {
-            return ((BridgeMenuItemImpl) menuItem).getViewCookie();
-        }
-
-        return null;
-    }
-
-    public void invalidateRenderingSize() {
-        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public boolean isAlphaChannelImage() {
-        return mIsAlphaChannelImage;
-    }
-
-    public List<ViewInfo> getViewInfos() {
-        return mViewInfoList;
-    }
-
-    public List<ViewInfo> getSystemViewInfos() {
-        return mSystemViewInfoList;
-    }
-
-    public Map<Object, PropertiesMap> getDefaultProperties() {
-        return getContext().getDefaultProperties();
-    }
-
-    public void setScene(RenderSession session) {
-        mScene = session;
-    }
-
-    public RenderSession getSession() {
-        return mScene;
-    }
-
-    public void dispose() {
-        boolean createdLooper = false;
-        if (Looper.myLooper() == null) {
-            // Detaching the root view from the window will try to stop any running animations.
-            // The stop method checks that it can run in the looper so, if there is no current
-            // looper, we create a temporary one to complete the shutdown.
-            Bridge.prepareThread();
-            createdLooper = true;
-        }
-        AttachInfo_Accessor.detachFromWindow(mViewRoot);
-        if (mCanvas != null) {
-            mCanvas.release();
-            mCanvas = null;
-        }
-        if (mViewInfoList != null) {
-            mViewInfoList.clear();
-        }
-        if (mSystemViewInfoList != null) {
-            mSystemViewInfoList.clear();
-        }
-        mImage = null;
-        mViewRoot = null;
-        mContentRoot = null;
-
-        if (createdLooper) {
-            Bridge.cleanupThread();
-            Choreographer_Delegate.dispose();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
deleted file mode 100644
index 75f9ec5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.ninepatch.NinePatch;
-import com.android.ninepatch.NinePatchChunk;
-import com.android.resources.Density;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.res.ColorStateList;
-import android.content.res.ComplexColor;
-import android.content.res.ComplexColor_Accessor;
-import android.content.res.FontResourcesParser;
-import android.content.res.GradientColor;
-import android.content.res.Resources.Theme;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Color;
-import android.graphics.NinePatch_Delegate;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.Typeface_Accessor;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.text.FontConfig;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to provide various conversion method used in handling android resources.
- */
-public final class ResourceHelper {
-
-    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
-    private final static float[] sFloatOut = new float[1];
-
-    private final static TypedValue mValue = new TypedValue();
-
-    /**
-     * Returns the color value represented by the given string value
-     * @param value the color value
-     * @return the color as an int
-     * @throws NumberFormatException if the conversion failed.
-     */
-    public static int getColor(String value) {
-        if (value != null) {
-            value = value.trim();
-            if (!value.startsWith("#")) {
-                if (value.startsWith(SdkConstants.PREFIX_THEME_REF)) {
-                    throw new NumberFormatException(String.format(
-                            "Attribute '%s' not found. Are you using the right theme?", value));
-                }
-                throw new NumberFormatException(
-                        String.format("Color value '%s' must start with #", value));
-            }
-
-            value = value.substring(1);
-
-            // make sure it's not longer than 32bit
-            if (value.length() > 8) {
-                throw new NumberFormatException(String.format(
-                        "Color value '%s' is too long. Format is either" +
-                        "#AARRGGBB, #RRGGBB, #RGB, or #ARGB",
-                        value));
-            }
-
-            if (value.length() == 3) { // RGB format
-                char[] color = new char[8];
-                color[0] = color[1] = 'F';
-                color[2] = color[3] = value.charAt(0);
-                color[4] = color[5] = value.charAt(1);
-                color[6] = color[7] = value.charAt(2);
-                value = new String(color);
-            } else if (value.length() == 4) { // ARGB format
-                char[] color = new char[8];
-                color[0] = color[1] = value.charAt(0);
-                color[2] = color[3] = value.charAt(1);
-                color[4] = color[5] = value.charAt(2);
-                color[6] = color[7] = value.charAt(3);
-                value = new String(color);
-            } else if (value.length() == 6) {
-                value = "FF" + value;
-            }
-
-            // this is a RRGGBB or AARRGGBB value
-
-            // Integer.parseInt will fail to parse strings like "ff191919", so we use
-            // a Long, but cast the result back into an int, since we know that we're only
-            // dealing with 32 bit values.
-            return (int)Long.parseLong(value, 16);
-        }
-
-        throw new NumberFormatException();
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     * @param theme the theme to use when resolving the complex color
-     * @param allowGradients when false, only {@link ColorStateList} will be returned. If a {@link
-     * GradientColor} is found, null will be returned.
-     */
-    @Nullable
-    private static ComplexColor getInternalComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context, @Nullable Theme theme, boolean allowGradients) {
-        String value = resValue.getValue();
-        if (value == null || RenderResources.REFERENCE_NULL.equals(value)) {
-            return null;
-        }
-
-        XmlPullParser parser = null;
-        // first check if the value is a file (xml most likely)
-        Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-        if (psiParserSupport != null && psiParserSupport) {
-            parser = context.getLayoutlibCallback().getXmlFileParser(value);
-        }
-        if (parser == null) {
-            File f = new File(value);
-            if (f.isFile()) {
-                // let the framework inflate the color from the XML file, by
-                // providing an XmlPullParser
-                try {
-                    parser = ParserFactory.create(f);
-                } catch (XmlPullParserException | FileNotFoundException e) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed to parse file " + value, e, null /*data*/);
-                }
-            }
-        }
-
-        if (parser != null) {
-            try {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, resValue.isFramework());
-                try {
-                    // Advance the parser to the first element so we can detect if it's a
-                    // color list or a gradient color
-                    int type;
-                    //noinspection StatementWithEmptyBody
-                    while ((type = blockParser.next()) != XmlPullParser.START_TAG
-                            && type != XmlPullParser.END_DOCUMENT) {
-                        // Seek parser to start tag.
-                    }
-
-                    if (type != XmlPullParser.START_TAG) {
-                        assert false : "No start tag found";
-                        return null;
-                    }
-
-                    final String name = blockParser.getName();
-                    if (allowGradients && "gradient".equals(name)) {
-                        return ComplexColor_Accessor.createGradientColorFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    } else if ("selector".equals(name)) {
-                        return ComplexColor_Accessor.createColorStateListFromXmlInner(
-                                context.getResources(),
-                                blockParser, blockParser,
-                                theme);
-                    }
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to configure parser for " + value, e, null /*data*/);
-                // we'll return null below.
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is
-                // checked before attempting to parse it.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                        "Failed to parse file " + value, e, null /*data*/);
-
-                return null;
-            }
-        } else {
-            // try to load the color state list from an int
-            try {
-                int color = getColor(value);
-                return ColorStateList.valueOf(color);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                        "Failed to convert " + value + " into a ColorStateList", e,
-                        null /*data*/);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link ColorStateList} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ColorStateList getColorStateList(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return (ColorStateList) getInternalComplexColor(resValue, context, context.getTheme(),
-                false);
-    }
-
-    /**
-     * Returns a {@link ComplexColor} from the given {@link ResourceValue}
-     *
-     * @param resValue the value containing a color value or a file path to a complex color
-     * definition
-     * @param context the current context
-     */
-    @Nullable
-    public static ComplexColor getComplexColor(@NonNull ResourceValue resValue,
-            @NonNull BridgeContext context) {
-        return getInternalComplexColor(resValue, context, context.getTheme(), true);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
-        return getDrawable(value, context, null);
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context the current context
-     * @param theme the theme to be used to inflate the drawable.
-     */
-    public static Drawable getDrawable(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-        String stringValue = value.getValue();
-        if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
-            return null;
-        }
-
-        String lowerCaseValue = stringValue.toLowerCase();
-
-        Density density = Density.MEDIUM;
-        if (value instanceof DensityBasedResourceValue) {
-            density = ((DensityBasedResourceValue) value).getResourceDensity();
-        }
-
-        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File file = new File(stringValue);
-            if (file.isFile()) {
-                try {
-                    return getNinePatchDrawable(new FileInputStream(file), density,
-                            value.isFramework(), stringValue, context);
-                } catch (IOException e) {
-                    // failed to read the file, we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
-                }
-            }
-
-            return null;
-        } else if (lowerCaseValue.endsWith(".xml") || stringValue.startsWith("@aapt:_aapt/")) {
-            // create a block parser for the file
-            try {
-                XmlPullParser parser = context.getLayoutlibCallback().getParser(value);
-                if (parser == null) {
-                    File drawableFile = new File(stringValue);
-                    if (drawableFile.isFile()) {
-                        parser = ParserFactory.create(drawableFile);
-                    }
-                }
-
-                BridgeXmlBlockParser blockParser =
-                        new BridgeXmlBlockParser(parser, context, value.isFramework());
-                try {
-                    return Drawable.createFromXml(context.getResources(), blockParser, theme);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } catch (Exception e) {
-                // this is an error and not warning since the file existence is checked before
-                // attempting to parse it.
-                Bridge.getLog().error(null, "Failed to parse file " + stringValue, e,
-                        null /*data*/);
-            }
-
-            return null;
-        } else {
-            File bmpFile = new File(stringValue);
-            if (bmpFile.isFile()) {
-                try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                            value.isFramework() ? null : context.getProjectKey());
-
-                    if (bitmap == null) {
-                        bitmap =
-                                Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(stringValue, bitmap,
-                                value.isFramework() ? null : context.getProjectKey());
-                    }
-
-                    return new BitmapDrawable(context.getResources(), bitmap);
-                } catch (IOException e) {
-                    // we'll return null below
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                            "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/);
-                }
-            } else {
-                // attempt to get a color from the value
-                try {
-                    int color = getColor(stringValue);
-                    return new ColorDrawable(color);
-                } catch (NumberFormatException e) {
-                    // we'll return null below.
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
-                            "Failed to convert " + stringValue + " into a drawable", e,
-                            null /*data*/);
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(String fontName, BridgeContext context, Theme theme, boolean
-            isFramework) {
-        if (fontName == null) {
-            return null;
-        }
-
-        if (Typeface_Accessor.isSystemFont(fontName)) {
-            // Shortcut for the case where we are asking for a system font name. Those are not
-            // loaded using external resources.
-            return null;
-        }
-
-        // Check if this is an asset that we've already loaded dynamically
-        Typeface typeface = Typeface.findFromCache(context.getAssets(), fontName);
-        if (typeface != null) {
-            return typeface;
-        }
-
-        String lowerCaseValue = fontName.toLowerCase();
-        if (lowerCaseValue.endsWith(".xml")) {
-            // create a block parser for the file
-            Boolean psiParserSupport = context.getLayoutlibCallback().getFlag(
-                    RenderParamsFlags.FLAG_KEY_XML_FILE_PARSER_SUPPORT);
-            XmlPullParser parser = null;
-            if (psiParserSupport != null && psiParserSupport) {
-                parser = context.getLayoutlibCallback().getXmlFileParser(fontName);
-            }
-            else {
-                File f = new File(fontName);
-                if (f.isFile()) {
-                    try {
-                        parser = ParserFactory.create(f);
-                    } catch (XmlPullParserException | FileNotFoundException e) {
-                        // this is an error and not warning since the file existence is checked before
-                        // attempting to parse it.
-                        Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                                e, null /*data*/);
-                    }
-                }
-            }
-
-            if (parser != null) {
-                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
-                        parser, context, isFramework);
-                try {
-                    FontResourcesParser.FamilyResourceEntry entry =
-                            FontResourcesParser.parse(blockParser, context.getResources());
-                    typeface = Typeface.createFromResources(entry, context.getAssets(),
-                            fontName);
-                } catch (XmlPullParserException | IOException e) {
-                    Bridge.getLog().error(null, "Failed to parse file " + fontName,
-                            e, null /*data*/);
-                } finally {
-                    blockParser.ensurePopped();
-                }
-            } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        String.format("File %s does not exist (or is not a file)", fontName),
-                        null /*data*/);
-            }
-        } else {
-            typeface = Typeface.createFromResources(context.getAssets(), fontName, 0);
-        }
-
-        return typeface;
-    }
-
-    /**
-     * Returns a {@link Typeface} given a font name. The font name, can be a system font family
-     * (like sans-serif) or a full path if the font is to be loaded from resources.
-     */
-    public static Typeface getFont(ResourceValue value, BridgeContext context, Theme theme) {
-        if (value == null) {
-            return null;
-        }
-
-        return getFont(value.getValue(), context, theme, value.isFramework());
-    }
-
-    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
-            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
-        // see if we still have both the chunk and the bitmap in the caches
-        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
-                isFramework ? null : context.getProjectKey());
-        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
-                isFramework ? null : context.getProjectKey());
-
-        // if either chunk or bitmap is null, then we reload the 9-patch file.
-        if (chunk == null || bitmap == null) {
-            try {
-                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
-                        false /* convert */);
-                if (ninePatch != null) {
-                    if (chunk == null) {
-                        chunk = ninePatch.getChunk();
-
-                        Bridge.setCached9Patch(cacheKey, chunk,
-                                isFramework ? null : context.getProjectKey());
-                    }
-
-                    if (bitmap == null) {
-                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
-                                false /*isMutable*/,
-                                density);
-
-                        Bridge.setCachedBitmap(cacheKey, bitmap,
-                                isFramework ? null : context.getProjectKey());
-                    }
-                }
-            } catch (MalformedURLException e) {
-                // URL is wrong, we'll return null below
-            }
-        }
-
-        if (chunk != null && bitmap != null) {
-            int[] padding = chunk.getPadding();
-            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
-
-            return new NinePatchDrawable(context.getResources(), bitmap,
-                    NinePatch_Delegate.serialize(chunk),
-                    paddingRect, null);
-        }
-
-        return null;
-    }
-
-    /**
-     * Looks for an attribute in the current theme.
-     *
-     * @param resources the render resources
-     * @param name the name of the attribute
-     * @param defaultValue the default value.
-     * @param isFrameworkAttr if the attribute is in android namespace
-     * @return the value of the attribute or the default one if not found.
-     */
-    public static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name,
-            boolean isFrameworkAttr, boolean defaultValue) {
-        ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr);
-        value = resources.resolveResValue(value);
-        if (value == null) {
-            return defaultValue;
-        }
-        return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
-    }
-
-    // ------- TypedValue stuff
-    // This is taken from //device/libs/utils/ResourceTypes.cpp
-
-    private static final class UnitEntry {
-        String name;
-        int type;
-        int unit;
-        float scale;
-
-        UnitEntry(String name, int type, int unit, float scale) {
-            this.name = name;
-            this.type = type;
-            this.unit = unit;
-            this.scale = scale;
-        }
-    }
-
-    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
-        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
-        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
-        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
-        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
-        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
-        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
-        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
-    };
-
-    /**
-     * Returns the raw value from the given attribute float-type value string.
-     * This object is only valid until the next call on to {@link ResourceHelper}.
-     */
-    public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
-        if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Parse a float attribute and return the parsed value into a given TypedValue.
-     * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
-     * @param value the string value of the attribute
-     * @param outValue the TypedValue to receive the parsed value
-     * @param requireUnit whether the value is expected to contain a unit.
-     * @return true if success.
-     */
-    public static boolean parseFloatAttribute(String attribute, @NonNull String value,
-            TypedValue outValue, boolean requireUnit) {
-        assert !requireUnit || attribute != null;
-
-        // remove the space before and after
-        value = value.trim();
-        int len = value.length();
-
-        if (len <= 0) {
-            return false;
-        }
-
-        // check that there's no non ascii characters.
-        char[] buf = value.toCharArray();
-        for (int i = 0 ; i < len ; i++) {
-            if (buf[i] > 255) {
-                return false;
-            }
-        }
-
-        // check the first character
-        if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') {
-            return false;
-        }
-
-        // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(value);
-        if (m.matches()) {
-            String f_str = m.group(1);
-            String end = m.group(2);
-
-            float f;
-            try {
-                f = Float.parseFloat(f_str);
-            } catch (NumberFormatException e) {
-                // this shouldn't happen with the regexp above.
-                return false;
-            }
-
-            if (end.length() > 0 && end.charAt(0) != ' ') {
-                // Might be a unit...
-                if (parseUnit(end, outValue, sFloatOut)) {
-                    computeTypedValue(outValue, f, sFloatOut[0]);
-                    return true;
-                }
-                return false;
-            }
-
-            // make sure it's only spaces at the end.
-            end = end.trim();
-
-            if (end.length() == 0) {
-                if (outValue != null) {
-                    if (!requireUnit) {
-                        outValue.type = TypedValue.TYPE_FLOAT;
-                        outValue.data = Float.floatToIntBits(f);
-                    } else {
-                        // no unit when required? Use dp and out an error.
-                        applyUnit(sUnitNames[1], outValue, sFloatOut);
-                        computeTypedValue(outValue, f, sFloatOut[0]);
-
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
-                                String.format(
-                                        "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
-                                        value, attribute),
-                                null);
-                    }
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static void computeTypedValue(TypedValue outValue, float value, float scale) {
-        value *= scale;
-        boolean neg = value < 0;
-        if (neg) {
-            value = -value;
-        }
-        long bits = (long)(value*(1<<23)+.5f);
-        int radix;
-        int shift;
-        if ((bits&0x7fffff) == 0) {
-            // Always use 23p0 if there is no fraction, just to make
-            // things easier to read.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        } else if ((bits&0xffffffffff800000L) == 0) {
-            // Magnitude is zero -- can fit in 0 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_0p23;
-            shift = 0;
-        } else if ((bits&0xffffffff80000000L) == 0) {
-            // Magnitude can fit in 8 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_8p15;
-            shift = 8;
-        } else if ((bits&0xffffff8000000000L) == 0) {
-            // Magnitude can fit in 16 bits of precision.
-            radix = TypedValue.COMPLEX_RADIX_16p7;
-            shift = 16;
-        } else {
-            // Magnitude needs entire range, so no fractional part.
-            radix = TypedValue.COMPLEX_RADIX_23p0;
-            shift = 23;
-        }
-        int mantissa = (int)(
-            (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-        if (neg) {
-            mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-        }
-        outValue.data |=
-            (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-            | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
-    }
-
-    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
-        str = str.trim();
-
-        for (UnitEntry unit : sUnitNames) {
-            if (unit.name.equals(str)) {
-                applyUnit(unit, outValue, outScale);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
-        outValue.type = unit.type;
-        // COMPLEX_UNIT_SHIFT is 0 and hence intelliJ complains about it. Suppress the warning.
-        //noinspection PointlessBitwiseExpression
-        outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-        outScale[0] = unit.scale;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
deleted file mode 100644
index 9bd0015..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import java.util.ArrayList;
-
-/**
- * Custom Stack implementation on top of an {@link ArrayList} instead of
- * using {@link java.util.Stack} which is on top of a vector.
- *
- * @param <T>
- */
-public class Stack<T> extends ArrayList<T> {
-
-    private static final long serialVersionUID = 1L;
-
-    public Stack() {
-        super();
-    }
-
-    public Stack(int size) {
-        super(size);
-    }
-
-    /**
-     * Pushes the given object to the stack
-     * @param object the object to push
-     */
-    public void push(T object) {
-        add(object);
-    }
-
-    /**
-     * Remove the object at the top of the stack and returns it.
-     * @return the removed object or null if the stack was empty.
-     */
-    public T pop() {
-        if (size() > 0) {
-            return remove(size() - 1);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the object at the top of the stack.
-     * @return the object at the top or null if the stack is empty.
-     */
-    public T peek() {
-        if (size() > 0) {
-            return get(size() - 1);
-        }
-
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
deleted file mode 100644
index 9fea167..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/SystemViewInfo.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.ide.common.rendering.api.ViewType;
-
-/**
- * ViewInfo for views added by the platform.
- */
-public class SystemViewInfo extends ViewInfo {
-
-    private ViewType mViewType;
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom) {
-        super(name, cookie, left, top, right, bottom);
-    }
-
-    public SystemViewInfo(String name, Object cookie, int left, int top,
-            int right, int bottom, Object viewObject, Object layoutParamsObject) {
-        super(name, cookie, left, top, right, bottom, viewObject,
-                layoutParamsObject);
-    }
-
-    @Override
-    public ViewType getViewType() {
-        if (mViewType != null) {
-            return mViewType;
-        }
-        return ViewType.SYSTEM_UNKNOWN;
-    }
-
-    public void setViewType(ViewType type) {
-        mViewType = type;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
deleted file mode 100644
index c0ca1d5..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.IProjectCallback.ViewAttribute;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.Checkable;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * A Helper class to do fake data binding in {@link AdapterView} objects.
- */
-public class AdapterHelper {
-
-    @SuppressWarnings("deprecation")
-    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
-            LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
-        // we don't care about recycling here because we never scroll.
-        DataBindingItem dataBindingItem = item.getDataBindingItem();
-
-        BridgeContext context = RenderAction.getCurrentContext();
-
-        Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
-                parent, false /*attachToRoot*/, skipCallbackParser);
-
-        View view = pair.getFirst();
-        skipCallbackParser |= pair.getSecond();
-
-        if (view != null) {
-            fillView(context, view, item, parentItem, callback, adapterRef);
-        } else {
-            // create a text view to display an error.
-            TextView tv = new TextView(context);
-            tv.setText("Unable to find layout: " + dataBindingItem.getViewReference().getName());
-            view = tv;
-        }
-
-        return Pair.of(view, skipCallbackParser);
-    }
-
-    private static void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem, LayoutlibCallback callback, ResourceReference adapterRef) {
-        if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) view;
-            final int count = group.getChildCount();
-            for (int i = 0 ; i < count ; i++) {
-                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
-            }
-        } else {
-            int id = view.getId();
-            if (id != 0) {
-                ResourceReference resolvedRef = context.resolveId(id);
-                if (resolvedRef != null) {
-                    int fullPosition = item.getFullPosition();
-                    int positionPerType = item.getPositionPerType();
-                    int fullParentPosition = parentItem != null ? parentItem.getFullPosition() : 0;
-                    int parentPositionPerType = parentItem != null ?
-                            parentItem.getPositionPerType() : 0;
-
-                    if (view instanceof TextView) {
-                        TextView tv = (TextView) view;
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for TEXT. Expected String, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                tv.setText((String) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof Checkable) {
-                        Checkable cb = (Checkable) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                cb.setChecked((Boolean) value);
-                            }
-                        }
-                    }
-
-                    if (view instanceof ImageView) {
-                        ImageView iv = (ImageView) view;
-
-                        Object value = callback.getAdapterItemValue(
-                                adapterRef, context.getViewKey(view),
-                                item.getDataBindingItem().getViewReference(),
-                                fullPosition, positionPerType,
-                                fullParentPosition, parentPositionPerType,
-                                resolvedRef, ViewAttribute.SRC, iv.getDrawable());
-                        if (value != null) {
-                            if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
-                                        "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
-                                        value.getClass().getName()), null);
-                            } else {
-                                // FIXME
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
deleted file mode 100644
index 8e28dba..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.android.ide.common.rendering.api.DataBindingItem;
-
-/**
- * This is the items provided by the adapter. They are dynamically generated.
- */
-final class AdapterItem {
-    private final DataBindingItem mItem;
-    private final int mType;
-    private final int mFullPosition;
-    private final int mPositionPerType;
-    private List<AdapterItem> mChildren;
-
-    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
-            int positionPerType) {
-        mItem = item;
-        mType = type;
-        mFullPosition = fullPosition;
-        mPositionPerType = positionPerType;
-    }
-
-    void addChild(AdapterItem child) {
-        if (mChildren == null) {
-            mChildren = new ArrayList<AdapterItem>();
-        }
-
-        mChildren.add(child);
-    }
-
-    List<AdapterItem> getChildren() {
-        if (mChildren != null) {
-            return mChildren;
-        }
-
-        return Collections.emptyList();
-    }
-
-    int getType() {
-        return mType;
-    }
-
-    int getFullPosition() {
-        return mFullPosition;
-    }
-
-    int getPositionPerType() {
-        return mPositionPerType;
-    }
-
-    DataBindingItem getDataBindingItem() {
-        return mItem;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
deleted file mode 100644
index 142eac1..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.ListAdapter;
-import android.widget.SpinnerAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Fake adapter to do fake data binding in {@link AdapterView} objects for {@link ListAdapter}
- * and {@link SpinnerAdapter}.
- *
- */
-public class FakeAdapter extends BaseAdapter {
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-    private boolean mSkipCallbackParser = false;
-
-    public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        final int repeatCount = binding.getRepeatCount();
-        final int itemCount = binding.getItemCount();
-
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // We put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : binding) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = mTypes.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = mTypes.size();
-                    mTypes.add(viewRef);
-                }
-
-                int count = dataBindingItem.getCount();
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    mItems.add(new AdapterItem(dataBindingItem, typeIndex, mItems.size(), index++));
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return true;
-    }
-
-    @Override
-    public int getCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mItems.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        return mItems.get(position).getType();
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(position);
-        @SuppressWarnings("deprecation")
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return mTypes.size();
-    }
-
-    // ---- SpinnerAdapter
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        // pass
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
deleted file mode 100644
index 344b17e..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl.binding;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.DataBindingItem;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
-
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ExpandableListAdapter;
-import android.widget.HeterogeneousExpandableList;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("deprecation")
-public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
-
-    private final LayoutlibCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private boolean mSkipCallbackParser = false;
-
-    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-
-    // don't use a set because the order is important.
-    private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
-    private final List<ResourceReference> mChildrenTypes = new ArrayList<ResourceReference>();
-
-    public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            LayoutlibCallback callback) {
-        mAdapterRef = adapterRef;
-        mCallback = callback;
-
-        createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
-    }
-
-    private void createItems(Iterable<DataBindingItem> iterable, final int itemCount,
-            final int repeatCount, List<ResourceReference> types, int depth) {
-        // Need an array to count for each type.
-        // This is likely too big, but is the max it can be.
-        int[] typeCount = new int[itemCount];
-
-        // we put several repeating sets.
-        for (int r = 0 ; r < repeatCount ; r++) {
-            // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : iterable) {
-                ResourceReference viewRef = dataBindingItem.getViewReference();
-                int typeIndex = types.indexOf(viewRef);
-                if (typeIndex == -1) {
-                    typeIndex = types.size();
-                    types.add(viewRef);
-                }
-
-                List<DataBindingItem> children = dataBindingItem.getChildren();
-                int count = dataBindingItem.getCount();
-
-                // if there are children, we use the count as a repeat count for the children.
-                if (children.size() > 0) {
-                    count = 1;
-                }
-
-                int index = typeCount[typeIndex];
-                typeCount[typeIndex] += count;
-
-                for (int k = 0 ; k < count ; k++) {
-                    AdapterItem item = new AdapterItem(dataBindingItem, typeIndex, mItems.size(),
-                            index++);
-                    mItems.add(item);
-
-                    if (children.size() > 0) {
-                        createItems(dataBindingItem, depth + 1);
-                    }
-                }
-            }
-        }
-    }
-
-    private void createItems(DataBindingItem item, int depth) {
-        if (depth == 2) {
-            createItems(item, item.getChildren().size(), item.getCount(), mChildrenTypes, depth);
-        }
-    }
-
-    private AdapterItem getChildItem(int groupPosition, int childPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-
-        List<AdapterItem> children = item.getChildren();
-        return children.get(childPosition);
-    }
-
-    // ---- ExpandableListAdapter
-
-    @Override
-    public int getGroupCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public int getChildrenCount(int groupPosition) {
-        AdapterItem item = mItems.get(groupPosition);
-        return item.getChildren().size();
-    }
-
-    @Override
-    public Object getGroup(int groupPosition) {
-        return mItems.get(groupPosition);
-    }
-
-    @Override
-    public Object getChild(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition);
-    }
-
-    @Override
-    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
-            ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem item = mItems.get(groupPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
-                mCallback, mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
-            View convertView, ViewGroup parent) {
-        // we don't care about recycling here because we never scroll.
-        AdapterItem parentItem = mItems.get(groupPosition);
-        AdapterItem item = getChildItem(groupPosition, childPosition);
-        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
-                mAdapterRef, mSkipCallbackParser);
-        mSkipCallbackParser = pair.getSecond();
-        return pair.getFirst();
-    }
-
-    @Override
-    public long getGroupId(int groupPosition) {
-        return groupPosition;
-    }
-
-    @Override
-    public long getChildId(int groupPosition, int childPosition) {
-        return childPosition;
-    }
-
-    @Override
-    public long getCombinedGroupId(long groupId) {
-        return groupId << 16 | 0x0000FFFF;
-    }
-
-    @Override
-    public long getCombinedChildId(long groupId, long childId) {
-        return groupId << 16 | childId;
-    }
-
-    @Override
-    public boolean isChildSelectable(int groupPosition, int childPosition) {
-        return true;
-    }
-
-    @Override
-    public void onGroupCollapsed(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void onGroupExpanded(int groupPosition) {
-        // pass
-    }
-
-    @Override
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mItems.isEmpty();
-    }
-
-    // ---- HeterogeneousExpandableList
-
-    @Override
-    public int getChildType(int groupPosition, int childPosition) {
-        return getChildItem(groupPosition, childPosition).getType();
-    }
-
-    @Override
-    public int getChildTypeCount() {
-        return mChildrenTypes.size();
-    }
-
-    @Override
-    public int getGroupType(int groupPosition) {
-        return mItems.get(groupPosition).getType();
-    }
-
-    @Override
-    public int getGroupTypeCount() {
-        return mGroupTypes.size();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
deleted file mode 100644
index 96cba78..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/libcore/io/BridgeBufferIterator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.libcore.io;
-
-import java.nio.ByteBuffer;
-
-import libcore.io.BufferIterator;
-
-/**
- * Provides an implementation of {@link BufferIterator} over a {@link ByteBuffer}.
- */
-public class BridgeBufferIterator extends BufferIterator {
-
-    private final long mSize;
-    private final ByteBuffer mByteBuffer;
-
-    public BridgeBufferIterator(long size, ByteBuffer buffer) {
-        mSize = size;
-        mByteBuffer = buffer;
-    }
-
-    @Override
-    public void seek(int offset) {
-        assert offset <= mSize;
-        mByteBuffer.position(offset);
-    }
-
-    @Override
-    public int pos() {
-        return mByteBuffer.position();
-    }
-
-    @Override
-    public void skip(int byteCount) {
-        int newPosition = mByteBuffer.position() + byteCount;
-        assert newPosition <= mSize;
-        mByteBuffer.position(newPosition);
-    }
-
-    @Override
-    public void readByteArray(byte[] dst, int dstOffset, int byteCount) {
-        assert dst.length >= dstOffset + byteCount;
-        mByteBuffer.get(dst, dstOffset, byteCount);
-    }
-
-    @Override
-    public byte readByte() {
-        return mByteBuffer.get();
-    }
-
-    @Override
-    public int readInt() {
-        return mByteBuffer.getInt();
-    }
-
-    @Override
-    public void readIntArray(int[] dst, int dstOffset, int intCount) {
-        while (--intCount >= 0) {
-            dst[dstOffset++] = mByteBuffer.getInt();
-        }
-    }
-
-    @Override
-    public short readShort() {
-        return mByteBuffer.getShort();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
deleted file mode 100644
index ae33e1d..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/ShadowBuffer.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-
-public class ShadowBuffer {
-
-    private int mWidth;
-    private int mHeight;
-    private Bitmap mBitmap;
-    private int[] mData;
-
-    public ShadowBuffer(int width, int height) {
-        mWidth = width;
-        mHeight = height;
-        mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
-        mData = new int[mBitmap.getWidth() * mBitmap.getHeight()];
-        mBitmap.getPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    public void generateTriangles(@NonNull float[] strip, float scale) {
-        for (int i = 0; i < strip.length - 8; i += 3) {
-            float fx3 = strip[i];
-            float fy3 = strip[i + 1];
-            float fz3 = scale * strip[i + 2];
-
-            float fx2 = strip[i + 3];
-            float fy2 = strip[i + 4];
-            float fz2 = scale * strip[i + 5];
-
-            float fx1 = strip[i + 6];
-            float fy1 = strip[i + 7];
-            float fz1 = scale * strip[i + 8];
-
-            if (fx1 * (fy2 - fy3) + fx2 * (fy3 - fy1) + fx3 * (fy1 - fy2) == 0) {
-                continue;
-            }
-
-            triangleZBuffMin(mData, mWidth, mHeight, fx3, fy3, fz3, fx2, fy2, fz2, fx1, fy1, fz1);
-            triangleZBuffMin(mData, mWidth, mHeight, fx1, fy1, fz1, fx2, fy2, fz2, fx3, fy3, fz3);
-        }
-        mBitmap.setPixels(mData, 0, mBitmap.getWidth(), 0, 0, mBitmap.getWidth(),
-                mBitmap.getHeight());
-    }
-
-    private void triangleZBuffMin(@NonNull int[] buff, int w, int h, float fx3, float fy3,
-            float fz3, float fx2, float fy2, float fz2, float fx1, float fy1, float fz1) {
-        if (((fx1 - fx2) * (fy3 - fy2) - (fy1 - fy2) * (fx3 - fx2)) < 0) {
-            float tmpX = fx1;
-            float tmpY = fy1;
-            float tmpZ = fz1;
-            fx1 = fx2;
-            fy1 = fy2;
-            fz1 = fz2;
-            fx2 = tmpX;
-            fy2 = tmpY;
-            fz2 = tmpZ;
-        }
-        double d = (fx1 * (fy3 - fy2) - fx2 * fy3 + fx3 * fy2 + (fx2 - fx3) * fy1);
-
-        if (d == 0) {
-            return;
-        }
-        float dx = (float) (-(fy1 * (fz3 - fz2) - fy2 * fz3 + fy3 * fz2 + (fy2 - fy3) * fz1) / d);
-        float dy = (float) ((fx1 * (fz3 - fz2) - fx2 * fz3 + fx3 * fz2 + (fx2 - fx3) * fz1) / d);
-        float zOff = (float) ((fx1 * (fy3 * fz2 - fy2 * fz3) + fy1 * (fx2 * fz3 - fx3 * fz2) +
-                (fx3 * fy2 - fx2 * fy3) * fz1) / d);
-
-        int Y1 = (int) (16.0f * fy1 + .5f);
-        int Y2 = (int) (16.0f * fy2 + .5f);
-        int Y3 = (int) (16.0f * fy3 + .5f);
-
-        int X1 = (int) (16.0f * fx1 + .5f);
-        int X2 = (int) (16.0f * fx2 + .5f);
-        int X3 = (int) (16.0f * fx3 + .5f);
-
-        int DX12 = X1 - X2;
-        int DX23 = X2 - X3;
-        int DX31 = X3 - X1;
-
-        int DY12 = Y1 - Y2;
-        int DY23 = Y2 - Y3;
-        int DY31 = Y3 - Y1;
-
-        int FDX12 = DX12 << 4;
-        int FDX23 = DX23 << 4;
-        int FDX31 = DX31 << 4;
-
-        int FDY12 = DY12 << 4;
-        int FDY23 = DY23 << 4;
-        int FDY31 = DY31 << 4;
-
-        int minX = (min(X1, X2, X3) + 0xF) >> 4;
-        int maxX = (max(X1, X2, X3) + 0xF) >> 4;
-        int minY = (min(Y1, Y2, Y3) + 0xF) >> 4;
-        int maxY = (max(Y1, Y2, Y3) + 0xF) >> 4;
-
-        if (minY < 0) {
-            minY = 0;
-        }
-        if (minX < 0) {
-            minX = 0;
-        }
-        if (maxX > w) {
-            maxX = w;
-        }
-        if (maxY > h) {
-            maxY = h;
-        }
-        int off = minY * w;
-
-        int C1 = DY12 * X1 - DX12 * Y1;
-        int C2 = DY23 * X2 - DX23 * Y2;
-        int C3 = DY31 * X3 - DX31 * Y3;
-
-        if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) {
-            C1++;
-        }
-        if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) {
-            C2++;
-        }
-        if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) {
-            C3++;
-        }
-        int CY1 = C1 + DX12 * (minY << 4) - DY12 * (minX << 4);
-        int CY2 = C2 + DX23 * (minY << 4) - DY23 * (minX << 4);
-        int CY3 = C3 + DX31 * (minY << 4) - DY31 * (minX << 4);
-
-        for (int y = minY; y < maxY; y++) {
-            int CX1 = CY1;
-            int CX2 = CY2;
-            int CX3 = CY3;
-            float p = zOff + dy * y;
-            for (int x = minX; x < maxX; x++) {
-                if (CX1 > 0 && CX2 > 0 && CX3 > 0) {
-                    int point = x + off;
-                    float zVal = p + dx * x;
-                    buff[point] |= ((int) (zVal * 255)) << 24;
-                }
-                CX1 -= FDY12;
-                CX2 -= FDY23;
-                CX3 -= FDY31;
-            }
-            CY1 += FDX12;
-            CY2 += FDX23;
-            CY3 += FDX31;
-            off += w;
-        }
-    }
-
-    private int min(int x1, int x2, int x3) {
-        return (x1 > x2) ? ((x2 > x3) ? x3 : x2) : ((x1 > x3) ? x3 : x1);
-    }
-
-    private int max(int x1, int x2, int x3) {
-        return (x1 < x2) ? ((x2 < x3) ? x3 : x2) : ((x1 < x3) ? x3 : x1);
-    }
-
-    public void draw(@NonNull Canvas c) {
-        c.drawBitmap(mBitmap, 0, 0, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
deleted file mode 100644
index 33375ff..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/shadowutil/SpotShadow.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.shadowutil;
-
-import android.annotation.NonNull;
-
-public class SpotShadow {
-
-    private static float rayIntersectPoly(@NonNull float[] poly, int polyLength, float px, float py,
-            float dx, float dy) {
-        int p1 = polyLength - 1;
-        for (int p2 = 0; p2 < polyLength; p2++) {
-            float p1x = poly[p1 * 2 + 0];
-            float p1y = poly[p1 * 2 + 1];
-            float p2x = poly[p2 * 2 + 0];
-            float p2y = poly[p2 * 2 + 1];
-            float div = (dx * (p1y - p2y) + dy * p2x - dy * p1x);
-            if (div != 0) {
-                float t = (dx * (p1y - py) + dy * px - dy * p1x) / (div);
-                if (t >= 0 && t <= 1) {
-                    float t2 = (p1x * (py - p2y) + p2x * (p1y - py) + px * (p2y - p1y)) / div;
-                    if (t2 > 0) {
-                        return t2;
-                    }
-                }
-            }
-            p1 = p2;
-        }
-        return Float.NaN;
-    }
-
-    private static void centroid2d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        float sumX = 0;
-        float sumY = 0;
-        int p1 = len - 1;
-        float area = 0;
-        for (int p2 = 0; p2 < len; p2++) {
-            float x1 = poly[p1 * 2 + 0];
-            float y1 = poly[p1 * 2 + 1];
-            float x2 = poly[p2 * 2 + 0];
-            float y2 = poly[p2 * 2 + 1];
-            float a = (x1 * y2 - x2 * y1);
-            sumX += (x1 + x2) * a;
-            sumY += (y1 + y2) * a;
-            area += a;
-            p1 = p2;
-        }
-
-        float centroidX = sumX / (3 * area);
-        float centroidY = sumY / (3 * area);
-        ret[0] = centroidX;
-        ret[1] = centroidY;
-    }
-
-    /**
-     * calculates the Centroid of a 3d polygon
-     * @param poly The flatten 3d vertices coordinates of polygon, the format is like
-     * [x0, y0, z0, x1, y1, z1, x2, ...]
-     * @param len The number of polygon vertices. So the length of poly should be len * 3.
-     * @param ret The array used to sotre the result. The length should be 3.
-     */
-    private static void centroid3d(@NonNull float[] poly, int len, @NonNull float[] ret) {
-        int n = len - 1;
-        double area = 0;
-        double cx = 0, cy = 0, cz = 0;
-        for (int i = 1; i < n; i++) {
-            int k = i + 1;
-            float a0 = poly[i * 3 + 0] - poly[0 * 3 + 0];
-            float a1 = poly[i * 3 + 1] - poly[0 * 3 + 1];
-            float a2 = poly[i * 3 + 2] - poly[0 * 3 + 2];
-            float b0 = poly[k * 3 + 0] - poly[0 * 3 + 0];
-            float b1 = poly[k * 3 + 1] - poly[0 * 3 + 1];
-            float b2 = poly[k * 3 + 2] - poly[0 * 3 + 2];
-            float c0 = a1 * b2 - b1 * a2;
-            float c1 = a2 * b0 - b2 * a0;
-            float c2 = a0 * b1 - b0 * a1;
-            double areaOfTriangle = Math.sqrt(c0 * c0 + c1 * c1 + c2 * c2);
-            area += areaOfTriangle;
-            cx += areaOfTriangle * (poly[i * 3 + 0] + poly[k * 3 + 0] + poly[0 * 3 + 0]);
-            cy += areaOfTriangle * (poly[i * 3 + 1] + poly[k * 3 + 1] + poly[0 * 3 + 1]);
-            cz += areaOfTriangle * (poly[i * 3 + 2] + poly[k * 3 + 2] + poly[0 * 3 + 2]);
-        }
-        ret[0] = (float) (cx / (3 * area));
-        ret[1] = (float) (cy / (3 * area));
-        ret[2] = (float) (cz / (3 * area));
-    }
-
-    /**
-     * Extracts the convex hull of a polygon.
-     * @param points The vertices coordinates of polygon
-     * @param pointsLength The number of polygon vertices. So the length of poly should be len * 3.
-     * @param retPoly retPoly is at most the size of the input polygon
-     * @return The number of points in the retPolygon
-     */
-    private static int hull(@NonNull float[] points, int pointsLength, @NonNull float[] retPoly) {
-        quicksortX(points, 0, pointsLength - 1);
-        int n = pointsLength;
-        float[] lUpper = new float[n * 2];
-        lUpper[0] = points[0];
-        lUpper[1] = points[1];
-        lUpper[2] = points[2];
-        lUpper[3] = points[3];
-
-        int lUpperSize = 2;
-
-        for (int i = 2; i < n; i++) {
-            lUpper[lUpperSize * 2 + 0] = points[i * 2 + 0];
-            lUpper[lUpperSize * 2 + 1] = points[i * 2 + 1];
-            lUpperSize++;
-
-            while (lUpperSize > 2 &&
-                    !rightTurn(lUpper[(lUpperSize - 3) * 2], lUpper[(lUpperSize - 3) * 2 + 1],
-                            lUpper[(lUpperSize - 2) * 2], lUpper[(lUpperSize - 2) * 2 + 1],
-                            lUpper[(lUpperSize - 1) * 2], lUpper[(lUpperSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lUpper[(lUpperSize - 2) * 2 + 0] = lUpper[(lUpperSize - 1) * 2 + 0];
-                lUpper[(lUpperSize - 2) * 2 + 1] = lUpper[(lUpperSize - 1) * 2 + 1];
-                lUpperSize--;
-            }
-        }
-
-        float[] lLower = new float[n * 2];
-        lLower[0] = points[(n - 1) * 2 + 0];
-        lLower[1] = points[(n - 1) * 2 + 1];
-        lLower[2] = points[(n - 2) * 2 + 0];
-        lLower[3] = points[(n - 2) * 2 + 1];
-
-        int lLowerSize = 2;
-
-        for (int i = n - 3; i >= 0; i--) {
-            lLower[lLowerSize * 2 + 0] = points[i * 2 + 0];
-            lLower[lLowerSize * 2 + 1] = points[i * 2 + 1];
-            lLowerSize++;
-
-            while (lLowerSize > 2 &&
-                    !rightTurn(lLower[(lLowerSize - 3) * 2], lLower[(lLowerSize - 3) * 2 + 1],
-                            lLower[(lLowerSize - 2) * 2], lLower[(lLowerSize - 2) * 2 + 1],
-                            lLower[(lLowerSize - 1) * 2], lLower[(lLowerSize - 1) * 2 + 1])) {
-                // Remove the middle point of the three last
-                lLower[(lLowerSize - 2) * 2 + 0] = lLower[(lLowerSize - 1) * 2 + 0];
-                lLower[(lLowerSize - 2) * 2 + 1] = lLower[(lLowerSize - 1) * 2 + 1];
-                lLowerSize--;
-            }
-        }
-
-        int count = 0;
-        for (int i = 0; i < lUpperSize; i++) {
-            retPoly[count * 2 + 0] = lUpper[i * 2 + 0];
-            retPoly[count * 2 + 1] = lUpper[i * 2 + 1];
-            count++;
-        }
-        for (int i = 1; i < lLowerSize - 1; i++) {
-            retPoly[count * 2 + 0] = lLower[i * 2 + 0];
-            retPoly[count * 2 + 1] = lLower[i * 2 + 1];
-            count++;
-        }
-        return count;
-    }
-
-    private static boolean rightTurn(float ax, float ay, float bx, float by, float cx, float cy) {
-        return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > 0.00001;
-    }
-
-    /**
-     * calculates the intersection of poly1 with poly2 and put in poly2
-     * @param poly1 The flatten 2d coordinates of polygon
-     * @param poly1length The vertices number of poly1
-     * @param poly2 The flatten 2d coordinates of polygon
-     * @param poly2length The vertices number of poly2
-     * @return number of vertices in poly2
-     */
-    private static int intersection(@NonNull float[] poly1, int poly1length, @NonNull float[] poly2,
-            int poly2length) {
-        makeClockwise(poly1, poly1length);
-        makeClockwise(poly2, poly2length);
-        float[] poly = new float[(poly1length * poly2length + 2) * 2];
-        int count = 0;
-        int pCount = 0;
-        for (int i = 0; i < poly1length; i++) {
-            if (pointInsidePolygon(poly1[i * 2 + 0], poly1[i * 2 + 1], poly2, poly2length)) {
-                poly[count * 2 + 0] = poly1[i * 2 + 0];
-                poly[count * 2 + 1] = poly1[i * 2 + 1];
-                count++;
-                pCount++;
-            }
-        }
-        int fromP1 = pCount;
-        for (int i = 0; i < poly2length; i++) {
-            if (pointInsidePolygon(poly2[i * 2 + 0], poly2[i * 2 + 1], poly1, poly1length)) {
-                poly[count * 2 + 0] = poly2[i * 2 + 0];
-                poly[count * 2 + 1] = poly2[i * 2 + 1];
-                count++;
-            }
-        }
-        int fromP2 = count - fromP1;
-        if (fromP1 == poly1length) { // use p1
-            for (int i = 0; i < poly1length; i++) {
-                poly2[i * 2 + 0] = poly1[i * 2 + 0];
-                poly2[i * 2 + 1] = poly1[i * 2 + 1];
-            }
-            return poly1length;
-        }
-        if (fromP2 == poly2length) { // use p2
-            return poly2length;
-        }
-        float[] intersection = new float[2];
-        for (int i = 0; i < poly2length; i++) {
-            for (int j = 0; j < poly1length; j++) {
-                int i1_by_2 = i * 2;
-                int i2_by_2 = ((i + 1) % poly2length) * 2;
-                int j1_by_2 = j * 2;
-                int j2_by_2 = ((j + 1) % poly1length) * 2;
-                boolean found =
-                        lineIntersection(poly2[i1_by_2 + 0], poly2[i1_by_2 + 1], poly2[i2_by_2 + 0],
-                                poly2[i2_by_2 + 1], poly1[j1_by_2 + 0], poly1[j1_by_2 + 1],
-                                poly1[j2_by_2 + 0], poly1[j2_by_2 + 1], intersection);
-                if (found) {
-                    poly[count * 2 + 0] = intersection[0];
-                    poly[count * 2 + 1] = intersection[1];
-                    count++;
-                } else {
-                    float dx = poly2[i * 2 + 0] - poly1[j * 2 + 0];
-                    float dy = poly2[i * 2 + 1] - poly1[j * 2 + 1];
-
-                    if (dx * dx + dy * dy < 0.01) {
-                        poly[count * 2 + 0] = poly2[i * 2 + 0];
-                        poly[count * 2 + 1] = poly2[i * 2 + 1];
-                        count++;
-                    }
-                }
-            }
-        }
-        if (count == 0) {
-            return 0;
-        }
-        float avgX = 0;
-        float avgY = 0;
-        for (int i = 0; i < count; i++) {
-            avgX += poly[i * 2 + 0];
-            avgY += poly[i * 2 + 1];
-        }
-        avgX /= count;
-        avgY /= count;
-
-        float[] ctr = new float[]{avgX, avgY};
-        sort(poly, count, ctr);
-        int size = count;
-
-        poly2[0] = poly[0];
-        poly2[1] = poly[1];
-
-        count = 1;
-        for (int i = 1; i < size; i++) {
-            float dx = poly[i * 2 + 0] - poly[(i - 1) * 2 + 0];
-            float dy = poly[i * 2 + 1] - poly[(i - 1) * 2 + 1];
-            if (dx * dx + dy * dy >= 0.01) {
-                poly2[count * 2 + 0] = poly[i * 2 + 0];
-                poly2[count * 2 + 1] = poly[i * 2 + 1];
-                count++;
-            }
-        }
-        return count;
-    }
-
-    public static void sort(@NonNull float[] poly, int polyLength, @NonNull float[] ctr) {
-        quicksortCircle(poly, 0, polyLength - 1, ctr);
-    }
-
-    public static float angle(float x1, float y1, @NonNull float[] ctr) {
-        return -(float) Math.atan2(x1 - ctr[0], y1 - ctr[1]);
-    }
-
-    private static void swapPair(@NonNull float[] points, int i, int j) {
-        float x = points[i * 2 + 0];
-        float y = points[i * 2 + 1];
-        points[i * 2 + 0] = points[j * 2 + 0];
-        points[i * 2 + 1] = points[j * 2 + 1];
-        points[j * 2 + 0] = x;
-        points[j * 2 + 1] = y;
-    }
-
-    private static void quicksortCircle(@NonNull float[] points, int low, int high,
-            @NonNull float[] ctr) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = angle(points[p * 2], points[p * 2 + 1], ctr);
-        while (i <= j) {
-            while (angle(points[i * 2 + 0], points[i * 2 + 1], ctr) < pivot) {
-                i++;
-            }
-            while (angle(points[j * 2 + 0], points[j * 2 + 1], ctr) > pivot) {
-                j--;
-            }
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortCircle(points, low, j, ctr);
-        }
-        if (i < high) {
-            quicksortCircle(points, i, high, ctr);
-        }
-    }
-
-    /**
-     * This function do Quick Sort by comparing X axis only.<br>
-     * Note that the input values of points are paired coordinates, e.g. {@code [x0, y0, x1, y1, x2,
-     * y2, ...]).}
-     * @param points The input point pairs. Every {@code (2 * i, 2 * i + 1)} points are pairs.
-     * @param low lowest index used to do quick sort sort
-     * @param high highest index used to do quick sort
-     */
-    private static void quicksortX(@NonNull float[] points, int low, int high) {
-        int i = low, j = high;
-        int p = low + (high - low) / 2;
-        float pivot = points[p * 2];
-        while (i <= j) {
-            while (points[i * 2 + 0] < pivot) {
-                i++;
-            }
-            while (points[j * 2 + 0] > pivot) {
-                j--;
-            }
-
-            if (i <= j) {
-                swapPair(points, i, j);
-                i++;
-                j--;
-            }
-        }
-        if (low < j) {
-            quicksortX(points, low, j);
-        }
-        if (i < high) {
-            quicksortX(points, i, high);
-        }
-    }
-
-    private static boolean pointInsidePolygon(float x, float y, @NonNull float[] poly, int len) {
-        boolean c = false;
-        float testX = x;
-        float testY = y;
-        for (int i = 0, j = len - 1; i < len; j = i++) {
-            if (((poly[i * 2 + 1] > testY) != (poly[j * 2 + 1] > testY)) && (testX <
-                    (poly[j * 2 + 0] - poly[i * 2 + 0]) * (testY - poly[i * 2 + 1]) /
-                            (poly[j * 2 + 1] - poly[i * 2 + 1]) + poly[i * 2 + 0])) {
-                c = !c;
-            }
-        }
-        return c;
-    }
-
-    private static void makeClockwise(@NonNull float[] polygon, int len) {
-        if (polygon == null || len == 0) {
-            return;
-        }
-        if (!isClockwise(polygon, len)) {
-            reverse(polygon, len);
-        }
-    }
-
-    private static boolean isClockwise(@NonNull float[] polygon, int len) {
-        float sum = 0;
-        float p1x = polygon[(len - 1) * 2 + 0];
-        float p1y = polygon[(len - 1) * 2 + 1];
-        for (int i = 0; i < len; i++) {
-            float p2x = polygon[i * 2 + 0];
-            float p2y = polygon[i * 2 + 1];
-            sum += p1x * p2y - p2x * p1y;
-            p1x = p2x;
-            p1y = p2y;
-        }
-        return sum < 0;
-    }
-
-    private static void reverse(@NonNull float[] polygon, int len) {
-        int n = len / 2;
-        for (int i = 0; i < n; i++) {
-            float tmp0 = polygon[i * 2 + 0];
-            float tmp1 = polygon[i * 2 + 1];
-            int k = len - 1 - i;
-            polygon[i * 2 + 0] = polygon[k * 2 + 0];
-            polygon[i * 2 + 1] = polygon[k * 2 + 1];
-            polygon[k * 2 + 0] = tmp0;
-            polygon[k * 2 + 1] = tmp1;
-        }
-    }
-
-    /**
-     * Intersects two lines in parametric form.
-     */
-    private static final boolean lineIntersection(float x1, float y1, float x2, float y2, float x3,
-            float y3, float x4, float y4, @NonNull float[] ret) {
-        float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-        if (d == 0.000f) {
-            return false;
-        }
-
-        float dx = (x1 * y2 - y1 * x2);
-        float dy = (x3 * y4 - y3 * x4);
-        float x = (dx * (x3 - x4) - (x1 - x2) * dy) / d;
-        float y = (dx * (y3 - y4) - (y1 - y2) * dy) / d;
-
-        if (((x - x1) * (x - x2) > 0.0000001) || ((x - x3) * (x - x4) > 0.0000001) ||
-                ((y - y1) * (y - y2) > 0.0000001) || ((y - y3) * (y - y4) > 0.0000001)) {
-            return false;
-        }
-        ret[0] = x;
-        ret[1] = y;
-        return true;
-    }
-
-    @NonNull
-    public static float[] calculateLight(float size, int points, float x, float y, float height) {
-        float[] ret = new float[points * 3];
-        for (int i = 0; i < points; i++) {
-            double angle = 2 * i * Math.PI / points;
-            ret[i * 3 + 0] = (float) Math.cos(angle) * size + x;
-            ret[i * 3 + 1] = (float) Math.sin(angle) * size + y;
-            ret[i * 3 + 2] = (height);
-        }
-        return ret;
-    }
-
-    /**
-     layers indicates the number of circular strips to generate.
-     Strength is how dark a shadow to generate.
-
-    /**
-     * This calculates a collection of triangles that represent the shadow cast by a polygonal
-     * light source (lightPoly) hitting a convex polygon (poly).
-     * @param lightPoly The flatten 3d coordinates of light
-     * @param lightPolyLength The vertices number of light polygon.
-     * @param poly The flatten 3d coordinates of item
-     * @param polyLength The vertices number of light polygon.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength
-     * @return true if the params is able to calculate a shadow, else false.
-     */
-    public static boolean calcShadow(@NonNull float[] lightPoly, int lightPolyLength,
-            @NonNull float[] poly, int polyLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        float[] shadowRegion = new float[lightPolyLength * polyLength * 2];
-        float[] outline = new float[polyLength * 2];
-        float[] umbra = new float[polyLength * lightPolyLength * 2];
-        int umbraLength = 0;
-
-        int k = 0;
-        for (int j = 0; j < lightPolyLength; j++) {
-            int m = 0;
-            for (int i = 0; i < polyLength; i++) {
-                float t = lightPoly[j * 3 + 2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = lightPoly[j * 3 + 2] / t;
-                float x = lightPoly[j * 3 + 0] - t * (lightPoly[j * 3 + 0] - poly[i * 3 + 0]);
-                float y = lightPoly[j * 3 + 1] - t * (lightPoly[j * 3 + 1] - poly[i * 3 + 1]);
-
-                shadowRegion[k * 2 + 0] = x;
-                shadowRegion[k * 2 + 1] = y;
-                outline[m * 2 + 0] = x;
-                outline[m * 2 + 1] = y;
-
-                k++;
-                m++;
-            }
-            if (umbraLength == 0) {
-                System.arraycopy(outline, 0, umbra, 0, polyLength);
-                umbraLength = polyLength;
-            } else {
-                umbraLength = intersection(outline, polyLength, umbra, umbraLength);
-                if (umbraLength == 0) {
-                    break;
-                }
-            }
-        }
-        int shadowRegionLength = k;
-
-        float[] penumbra = new float[k * 2];
-        int penumbraLength = hull(shadowRegion, shadowRegionLength, penumbra);
-        if (umbraLength < 3) {// no real umbra make a fake one
-            float[] p = new float[3];
-            centroid3d(lightPoly, lightPolyLength, p);
-            float[] centShadow = new float[polyLength * 2];
-            for (int i = 0; i < polyLength; i++) {
-                float t = p[2] - poly[i * 3 + 2];
-                if (t == 0) {
-                    return false;
-                }
-                t = p[2] / t;
-                float x = p[0] - t * (p[0] - poly[i * 3 + 0]);
-                float y = p[1] - t * (p[1] - poly[i * 3 + 1]);
-
-                centShadow[i * 2 + 0] = x;
-                centShadow[i * 2 + 1] = y;
-            }
-            float[] c = new float[2];
-            centroid2d(centShadow, polyLength, c);
-            for (int i = 0; i < polyLength; i++) {
-                centShadow[i * 2 + 0] = (c[0] * 9 + centShadow[i * 2 + 0]) / 10;
-                centShadow[i * 2 + 1] = (c[1] * 9 + centShadow[i * 2 + 1]) / 10;
-            }
-            umbra = centShadow; // fake umbra
-            umbraLength = polyLength; // same size as the original polygon
-        }
-
-        triangulateConcentricPolygon(penumbra, penumbraLength, umbra, umbraLength, rays, layers,
-                strength, retStrips);
-        return true;
-    }
-
-    /**
-     * triangulate concentric circles.
-     * This takes the inner and outer polygons of the umbra and penumbra and triangulates it.
-     * @param penumbra The 2d flatten vertices of penumbra polygons.
-     * @param penumbraLength The number of vertices in penumbra.
-     * @param umbra The 2d flatten vertices of umbra polygons.
-     * @param umbraLength The number of vertices in umbra.
-     * @param rays defines the number of points around the perimeter of the shadow to generate
-     * @param layers The number of shadow's fading.
-     * @param strength The factor of the black color of shadow.
-     * @param retStrips Used to store the calculated shadow strength.
-     */
-    private static void triangulateConcentricPolygon(@NonNull float[] penumbra, int penumbraLength,
-            @NonNull float[] umbra, int umbraLength, int rays, int layers, float strength,
-            @NonNull float[] retStrips) {
-        int rings = layers + 1;
-        double step = Math.PI * 2 / rays;
-        float[] retXY = new float[2];
-        centroid2d(umbra, umbraLength, retXY);
-        float cx = retXY[0];
-        float cy = retXY[1];
-
-        float[] t1 = new float[rays];
-        float[] t2 = new float[rays];
-
-        for (int i = 0; i < rays; i++) {
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-            t2[i] = rayIntersectPoly(umbra, umbraLength, cx, cy, dx, dy);
-            t1[i] = rayIntersectPoly(penumbra, penumbraLength, cx, cy, dx, dy);
-        }
-
-        int p = 0;
-        // Calculate the vertex
-        for (int r = 0; r < layers; r++) {
-            int startP = p;
-            for (int i = 0; i < rays; i++) {
-                float dx = (float) Math.cos(Math.PI / 4 + step * i);
-                float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-                for (int j = r; j < (r + 2); j++) {
-                    float jf = j / (float) (rings - 1);
-                    float t = t1[i] + jf * (t2[i] - t1[i]);
-                    float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-                    retStrips[p * 3 + 0] = dx * t + cx;
-                    retStrips[p * 3 + 1] = dy * t + cy;
-                    retStrips[p * 3 + 2] = jf * op * strength;
-                    p++;
-
-                }
-            }
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-            startP++;
-            retStrips[p * 3 + 0] = retStrips[startP * 3 + 0];
-            retStrips[p * 3 + 1] = retStrips[startP * 3 + 1];
-            retStrips[p * 3 + 2] = retStrips[startP * 3 + 2];
-            p++;
-        }
-        int oldP = p - 1;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-        p++;
-
-        // Skip the first point here, then make it same as last point later.
-        oldP = p;
-        p++;
-        for (int k = 0; k < rays; k++) {
-            int i = k / 2;
-            if ((k & 1) == 1) { // traverse the inside in a zig zag pattern
-                // for strips
-                i = rays - i - 1;
-            }
-            float dx = (float) Math.cos(Math.PI / 4 + step * i);
-            float dy = (float) Math.sin(Math.PI / 4 + step * i);
-
-            float jf = 1;
-
-            float t = t1[i] + jf * (t2[i] - t1[i]);
-            float op = (jf + 1 - 1 / (1 + (t - t1[i]) * (t - t1[i]))) / 2;
-
-            retStrips[p * 3 + 0] = dx * t + cx;
-            retStrips[p * 3 + 1] = dy * t + cy;
-            retStrips[p * 3 + 2] = jf * op * strength;
-            p++;
-        }
-        p = oldP;
-        retStrips[p * 3 + 0] = retStrips[oldP * 3 + 0];
-        retStrips[p * 3 + 1] = retStrips[oldP * 3 + 1];
-        retStrips[p * 3 + 2] = retStrips[oldP * 3 + 2];
-    }
-
-    public static int getStripSize(int rays, int layers) {
-        return (2 + rays + ((layers) * 2 * (rays + 1)));
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
deleted file mode 100644
index 0a9b9ec..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-
-import java.awt.geom.CubicCurve2D;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.QuadCurve2D;
-import java.util.ArrayList;
-
-import com.google.android.collect.Lists;
-
-/**
- * Class that returns iterators for a given path. These iterators are lightweight and can be reused
- * multiple times to iterate over the path.
- */
-public class CachedPathIteratorFactory {
-    /*
-     * A few conventions used in the code:
-     * Coordinates or coords arrays store segment coordinates. They use the same format as
-     * PathIterator#currentSegment coordinates array.
-     * float arrays store always points where the first element is X and the second is Y.
-     */
-
-    // This governs how accurate the approximation of the Path is.
-    private static final float PRECISION = 0.002f;
-
-    private final int mWindingRule;
-    private final int[] mTypes;
-    private final float[][] mCoordinates;
-    private final float[] mSegmentsLength;
-    private final float mTotalLength;
-
-    public CachedPathIteratorFactory(@NonNull PathIterator iterator) {
-        mWindingRule = iterator.getWindingRule();
-
-        ArrayList<Integer> typesArray = Lists.newArrayList();
-        ArrayList<float[]> pointsArray = Lists.newArrayList();
-        float[] points = new float[6];
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(points);
-            int nPoints = getNumberOfPoints(type) * 2; // 2 coordinates per point
-
-            typesArray.add(type);
-            float[] itemPoints = new float[nPoints];
-            System.arraycopy(points, 0, itemPoints, 0, nPoints);
-            pointsArray.add(itemPoints);
-            iterator.next();
-        }
-
-        mTypes = new int[typesArray.size()];
-        mCoordinates = new float[mTypes.length][];
-        for (int i = 0; i < typesArray.size(); i++) {
-            mTypes[i] = typesArray.get(i);
-            mCoordinates[i] = pointsArray.get(i);
-        }
-
-        // Do measurement
-        mSegmentsLength = new float[mTypes.length];
-
-        // Curves that we can reuse to estimate segments length
-        CubicCurve2D.Float cubicCurve = new CubicCurve2D.Float();
-        QuadCurve2D.Float quadCurve = new QuadCurve2D.Float();
-        float lastX = 0;
-        float lastY = 0;
-        float totalLength = 0;
-        for (int i = 0; i < mTypes.length; i++) {
-            switch (mTypes[i]) {
-                case PathIterator.SEG_CUBICTO:
-                    cubicCurve.setCurve(lastX, lastY,
-                            mCoordinates[i][0], mCoordinates[i][1], mCoordinates[i][2],
-                            mCoordinates[i][3], lastX = mCoordinates[i][4],
-                            lastY = mCoordinates[i][5]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(cubicCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_QUADTO:
-                    quadCurve.setCurve(lastX, lastY, mCoordinates[i][0], mCoordinates[i][1],
-                            lastX = mCoordinates[i][2], lastY = mCoordinates[i][3]);
-                    mSegmentsLength[i] =
-                            getFlatPathLength(quadCurve.getPathIterator(null, PRECISION));
-                    break;
-                case PathIterator.SEG_CLOSE:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY,
-                            lastX = mCoordinates[0][0],
-                            lastY = mCoordinates[0][1]);
-                    mCoordinates[i] = new float[2];
-                    // We convert a SEG_CLOSE segment to a SEG_LINETO so we do not have to worry
-                    // about this special case in the rest of the code.
-                    mTypes[i] = PathIterator.SEG_LINETO;
-                    mCoordinates[i][0] = mCoordinates[0][0];
-                    mCoordinates[i][1] = mCoordinates[0][1];
-                    break;
-                case PathIterator.SEG_MOVETO:
-                    mSegmentsLength[i] = 0;
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                    break;
-                case PathIterator.SEG_LINETO:
-                    mSegmentsLength[i] = (float) Point2D.distance(lastX, lastY, mCoordinates[i][0],
-                            mCoordinates[i][1]);
-                    lastX = mCoordinates[i][0];
-                    lastY = mCoordinates[i][1];
-                default:
-            }
-            totalLength += mSegmentsLength[i];
-        }
-
-        mTotalLength = totalLength;
-    }
-
-    private static void quadCurveSegment(float[] coords, float t0, float t1) {
-        // Calculate X and Y at 0.5 (We'll use this to reconstruct the control point later)
-        float mt = t0 + (t1 - t0) / 2;
-        float mu = 1 - mt;
-        float mx = mu * mu * coords[0] + 2 * mu * mt * coords[2] + mt * mt * coords[4];
-        float my = mu * mu * coords[1] + 2 * mu * mt * coords[3] + mt * mt * coords[5];
-
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // coords at t0
-        coords[0] = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        coords[1] = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-
-        // coords at t1
-        coords[4] = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        coords[5] = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-
-        // estimated control point at t'=0.5
-        coords[2] = 2 * mx - coords[0] / 2 - coords[4] / 2;
-        coords[3] = 2 * my - coords[1] / 2 - coords[5] / 2;
-    }
-
-    private static void cubicCurveSegment(float[] coords, float t0, float t1) {
-        // http://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
-        float u0 = 1 - t0;
-        float u1 = 1 - t1;
-
-        // Calculate the points at t0 and t1 for the quadratic curves formed by (P0, P1, P2) and
-        // (P1, P2, P3)
-        float qxa = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
-        float qxb = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
-        float qxc = coords[2] * u0 * u0 + coords[4] * 2 * t0 * u0 + coords[6] * t0 * t0;
-        float qxd = coords[2] * u1 * u1 + coords[4] * 2 * t1 * u1 + coords[6] * t1 * t1;
-
-        float qya = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
-        float qyb = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
-        float qyc = coords[3] * u0 * u0 + coords[5] * 2 * t0 * u0 + coords[7] * t0 * t0;
-        float qyd = coords[3] * u1 * u1 + coords[5] * 2 * t1 * u1 + coords[7] * t1 * t1;
-
-        // Linear interpolation
-        coords[0] = qxa * u0 + qxc * t0;
-        coords[1] = qya * u0 + qyc * t0;
-
-        coords[2] = qxa * u1 + qxc * t1;
-        coords[3] = qya * u1 + qyc * t1;
-
-        coords[4] = qxb * u0 + qxd * t0;
-        coords[5] = qyb * u0 + qyd * t0;
-
-        coords[6] = qxb * u1 + qxd * t1;
-        coords[7] = qyb * u1 + qyd * t1;
-    }
-
-    /**
-     * Returns the end point of a given segment
-     *
-     * @param type the segment type
-     * @param coords the segment coordinates array
-     * @param point the return array where the point will be stored
-     */
-    private static void getShapeEndPoint(int type, @NonNull float[] coords, @NonNull float[]
-            point) {
-        // start index of the end point for the segment type
-        int pointIndex = (getNumberOfPoints(type) - 1) * 2;
-        point[0] = coords[pointIndex];
-        point[1] = coords[pointIndex + 1];
-    }
-
-    /**
-     * Returns the number of points stored in a coordinates array for the given segment type.
-     */
-    private static int getNumberOfPoints(int segmentType) {
-        switch (segmentType) {
-            case PathIterator.SEG_QUADTO:
-                return 2;
-            case PathIterator.SEG_CUBICTO:
-                return 3;
-            case PathIterator.SEG_CLOSE:
-                return 0;
-            default:
-                return 1;
-        }
-    }
-
-    /**
-     * Returns the estimated length of a flat path. If the passed path is not flat (i.e. contains a
-     * segment that is not {@link PathIterator#SEG_CLOSE}, {@link PathIterator#SEG_MOVETO} or {@link
-     * PathIterator#SEG_LINETO} this method will fail.
-     */
-    private static float getFlatPathLength(@NonNull PathIterator iterator) {
-        float segment[] = new float[6];
-        float totalLength = 0;
-        float[] previousPoint = new float[2];
-        boolean isFirstPoint = true;
-
-        while (!iterator.isDone()) {
-            int type = iterator.currentSegment(segment);
-            assert type == PathIterator.SEG_LINETO || type == PathIterator.SEG_CLOSE || type ==
-                    PathIterator.SEG_MOVETO;
-
-            // MoveTo shouldn't affect the length
-            if (!isFirstPoint && type != PathIterator.SEG_MOVETO) {
-                totalLength += Point2D.distance(previousPoint[0], previousPoint[1], segment[0],
-                        segment[1]);
-            } else {
-                isFirstPoint = false;
-            }
-            previousPoint[0] = segment[0];
-            previousPoint[1] = segment[1];
-            iterator.next();
-        }
-
-        return totalLength;
-    }
-
-    /**
-     * Returns the estimated position along a path of the given length.
-     */
-    private void getPointAtLength(int type, @NonNull float[] coords, float lastX, float
-            lastY, float t, @NonNull float[] point) {
-        if (type == PathIterator.SEG_LINETO) {
-            point[0] = lastX + (coords[0] - lastX) * t;
-            point[1] = lastY + (coords[1] - lastY) * t;
-            // Return here, since we do not need a shape to estimate
-            return;
-        }
-
-        float[] curve = new float[8];
-        int lastPointIndex = (getNumberOfPoints(type) - 1) * 2;
-
-        System.arraycopy(coords, 0, curve, 2, coords.length);
-        curve[0] = lastX;
-        curve[1] = lastY;
-        if (type == PathIterator.SEG_CUBICTO) {
-            cubicCurveSegment(curve, 0f, t);
-        } else {
-            quadCurveSegment(curve, 0f, t);
-        }
-
-        point[0] = curve[2 + lastPointIndex];
-        point[1] = curve[2 + lastPointIndex + 1];
-    }
-
-    public CachedPathIterator iterator() {
-        return new CachedPathIterator();
-    }
-
-    /**
-     * Class that allows us to iterate over a path multiple times
-     */
-    public class CachedPathIterator implements PathIterator {
-        private int mNextIndex;
-
-        /**
-         * Current segment type.
-         *
-         * @see PathIterator
-         */
-        private int mCurrentType;
-
-        /**
-         * Stores the coordinates array of the current segment. The number of points stored depends
-         * on the segment type.
-         *
-         * @see PathIterator
-         */
-        private float[] mCurrentCoords = new float[6];
-        private float mCurrentSegmentLength;
-
-        /**
-         * Current segment length offset. When asking for the length of the current segment, the
-         * length will be reduced by this amount. This is useful when we are only using portions of
-         * the segment.
-         *
-         * @see #jumpToSegment(float)
-         */
-        private float mOffsetLength;
-
-        /** Point where the current segment started */
-        private float[] mLastPoint = new float[2];
-        private boolean isIteratorDone;
-
-        private CachedPathIterator() {
-            next();
-        }
-
-        public float getCurrentSegmentLength() {
-            return mCurrentSegmentLength;
-        }
-
-        @Override
-        public int getWindingRule() {
-            return mWindingRule;
-        }
-
-        @Override
-        public boolean isDone() {
-            return isIteratorDone;
-        }
-
-        @Override
-        public void next() {
-            if (mNextIndex >= mTypes.length) {
-                isIteratorDone = true;
-                return;
-            }
-
-            if (mNextIndex >= 1) {
-                // We've already called next() once so there is a previous segment in this path.
-                // We want to get the coordinates where the path ends.
-                getShapeEndPoint(mCurrentType, mCurrentCoords, mLastPoint);
-            } else {
-                // This is the first segment, no previous point so initialize to 0, 0
-                mLastPoint[0] = mLastPoint[1] = 0f;
-            }
-            mCurrentType = mTypes[mNextIndex];
-            mCurrentSegmentLength = mSegmentsLength[mNextIndex] - mOffsetLength;
-
-            if (mOffsetLength > 0f && (mCurrentType == SEG_CUBICTO || mCurrentType == SEG_QUADTO)) {
-                // We need to skip part of the start of the current segment (because
-                // mOffsetLength > 0)
-                float[] points = new float[8];
-
-                if (mNextIndex < 1) {
-                    points[0] = points[1] = 0f;
-                } else {
-                    getShapeEndPoint(mTypes[mNextIndex - 1], mCoordinates[mNextIndex - 1], points);
-                }
-
-                System.arraycopy(mCoordinates[mNextIndex], 0, points, 2,
-                        mCoordinates[mNextIndex].length);
-                float t0 = (mSegmentsLength[mNextIndex] - mCurrentSegmentLength) /
-                        mSegmentsLength[mNextIndex];
-                if (mCurrentType == SEG_CUBICTO) {
-                    cubicCurveSegment(points, t0, 1f);
-                } else {
-                    quadCurveSegment(points, t0, 1f);
-                }
-                System.arraycopy(points, 2, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
-            } else {
-                System.arraycopy(mCoordinates[mNextIndex], 0, mCurrentCoords, 0,
-                        mCoordinates[mNextIndex].length);
-            }
-
-            mOffsetLength = 0f;
-            mNextIndex++;
-        }
-
-        @Override
-        public int currentSegment(float[] coords) {
-            System.arraycopy(mCurrentCoords, 0, coords, 0, getNumberOfPoints(mCurrentType) * 2);
-            return mCurrentType;
-        }
-
-        @Override
-        public int currentSegment(double[] coords) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
-         * Returns the point where the current segment ends
-         */
-        public void getCurrentSegmentEnd(float[] point) {
-            point[0] = mLastPoint[0];
-            point[1] = mLastPoint[1];
-        }
-
-        /**
-         * Restarts the iterator and jumps all the segments of this path up to the length value.
-         */
-        public void jumpToSegment(float length) {
-            isIteratorDone = false;
-            if (length <= 0f) {
-                mNextIndex = 0;
-                return;
-            }
-
-            float accLength = 0;
-            float lastPoint[] = new float[2];
-            for (mNextIndex = 0; mNextIndex < mTypes.length; mNextIndex++) {
-                float segmentLength = mSegmentsLength[mNextIndex];
-                if (accLength + segmentLength >= length && mTypes[mNextIndex] != SEG_MOVETO) {
-                    float[] estimatedPoint = new float[2];
-                    getPointAtLength(mTypes[mNextIndex],
-                            mCoordinates[mNextIndex], lastPoint[0], lastPoint[1],
-                            (length - accLength) / segmentLength,
-                            estimatedPoint);
-
-                    // This segment makes us go further than length so we go back one step,
-                    // set a moveto and offset the length of the next segment by the length
-                    // of this segment that we've already used.
-                    mCurrentType = PathIterator.SEG_MOVETO;
-                    mCurrentCoords[0] = estimatedPoint[0];
-                    mCurrentCoords[1] = estimatedPoint[1];
-                    mCurrentSegmentLength = 0;
-
-                    // We need to offset next path length to account for the segment we've just
-                    // skipped.
-                    mOffsetLength = length - accLength;
-                    return;
-                }
-                accLength += segmentLength;
-                getShapeEndPoint(mTypes[mNextIndex], mCoordinates[mNextIndex], lastPoint);
-            }
-        }
-
-        /**
-         * Returns the current segment up to certain length. If the current segment is shorter than
-         * length, then the whole segment is returned. The segment coordinates are copied into the
-         * coords array.
-         *
-         * @return the segment type
-         */
-        public int currentSegment(@NonNull float[] coords, float length) {
-            int type = currentSegment(coords);
-            // If the length is greater than the current segment length, no need to find
-            // the cut point. Same if this is a SEG_MOVETO.
-            if (mCurrentSegmentLength <= length || type == SEG_MOVETO) {
-                return type;
-            }
-
-            float t = length / getCurrentSegmentLength();
-
-            // We find at which offset the end point is located within the coords array and set
-            // a new end point to cut the segment short
-            switch (type) {
-                case SEG_CUBICTO:
-                case SEG_QUADTO:
-                    float[] curve = new float[8];
-                    curve[0] = mLastPoint[0];
-                    curve[1] = mLastPoint[1];
-                    System.arraycopy(coords, 0, curve, 2, coords.length);
-                    if (type == SEG_CUBICTO) {
-                        cubicCurveSegment(curve, 0f, t);
-                    } else {
-                        quadCurveSegment(curve, 0f, t);
-                    }
-                    System.arraycopy(curve, 2, coords, 0, coords.length);
-                    break;
-                default:
-                    float[] point = new float[2];
-                    getPointAtLength(type, coords, mLastPoint[0], mLastPoint[1], t, point);
-                    coords[0] = point[0];
-                    coords[1] = point[1];
-            }
-
-            return type;
-        }
-
-        /**
-         * Returns the total length of the path
-         */
-        public float getTotalLength() {
-            return mTotalLength;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
deleted file mode 100644
index 82eab85..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-public class Debug {
-
-    public final static boolean DEBUG = false;
-
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
deleted file mode 100644
index 161bf41..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-
-import android.annotation.NonNull;
-import android.util.SparseArray;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DynamicIdMap {
-
-    private final Map<Pair<ResourceType, String>, Integer> mDynamicIds = new HashMap<>();
-    private final SparseArray<Pair<ResourceType, String>> mRevDynamicIds = new SparseArray<>();
-    private int mDynamicSeed;
-
-    public DynamicIdMap(int seed) {
-        mDynamicSeed = seed;
-    }
-
-    public void reset(int seed) {
-        mDynamicIds.clear();
-        mRevDynamicIds.clear();
-        mDynamicSeed = seed;
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param type the type of the resource
-     * @param name the name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(ResourceType type, String name) {
-        return getId(Pair.of(type, name));
-    }
-
-    /**
-     * Returns a dynamic integer for the given resource type/name, creating it if it doesn't
-     * already exist.
-     *
-     * @param resource the type/name of the resource
-     * @return an integer.
-     */
-    @NonNull
-    public Integer getId(Pair<ResourceType, String> resource) {
-        Integer value = mDynamicIds.get(resource);
-        if (value == null) {
-            value = ++mDynamicSeed;
-            mDynamicIds.put(resource, value);
-            mRevDynamicIds.put(value, resource);
-        }
-
-        return value;
-    }
-
-    public Pair<ResourceType, String> resolveId(int id) {
-        return mRevDynamicIds.get(id);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
deleted file mode 100644
index f149b6c..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/NinePatchInputStream.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-/**
- * Simpler wrapper around FileInputStream. This is used when the input stream represent
- * not a normal bitmap but a nine patch.
- * This is useful when the InputStream is created in a method but used in another that needs
- * to know whether this is 9-patch or not, such as BitmapFactory.
- */
-public class NinePatchInputStream extends FileInputStream {
-    private boolean mFakeMarkSupport = true;
-    public NinePatchInputStream(File file) throws FileNotFoundException {
-        super(file);
-    }
-
-    @Override
-    public boolean markSupported() {
-        // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
-        return mFakeMarkSupport || super.markSupported();
-
-    }
-
-    public void disableFakeMarkSupport() {
-        // disable fake mark support so that in case codec actually try to use them
-        // we don't lie to them.
-        mFakeMarkSupport = false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
deleted file mode 100644
index b89718f..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/ReflectionUtils.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Utility to convert checked Reflection exceptions to unchecked exceptions.
- */
-public class ReflectionUtils {
-
-    @NonNull
-    public static Method getMethod(@NonNull Class<?> clazz, @NonNull String name,
-            @Nullable Class<?>... params) throws ReflectionException {
-        try {
-            return clazz.getMethod(name, params);
-        } catch (NoSuchMethodException e) {
-            throw new ReflectionException(e);
-        }
-    }
-
-    @NonNull
-    public static Method getAccessibleMethod(@NonNull Class<?> clazz, @NonNull String name,
-      @Nullable Class<?>... params) throws ReflectionException {
-        Method method = getMethod(clazz, name, params);
-        method.setAccessible(true);
-
-        return method;
-    }
-
-    @Nullable
-    public static Object invoke(@NonNull Method method, @Nullable Object object,
-            @Nullable Object... args) throws ReflectionException {
-        Exception ex;
-        try {
-            return method.invoke(object, args);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            ex = e;
-        }
-        throw new ReflectionException(ex);
-    }
-
-    /**
-     * Check if the object is an instance of a class named {@code className}. This doesn't work
-     * for interfaces.
-     */
-    public static boolean isInstanceOf(Object object, String className) {
-        Class superClass = object.getClass();
-        while (superClass != null) {
-            String name = superClass.getName();
-            if (name.equals(className)) {
-                return true;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        return false;
-    }
-
-    @NonNull
-    public static Throwable getCause(@NonNull Throwable throwable) {
-        Throwable cause = throwable.getCause();
-        return cause == null ? throwable : cause;
-    }
-
-    /**
-     * Looks through the class hierarchy of {@code object} at runtime and returns the class matching
-     * the name {@code className}.
-     * <p>
-     * This is used when we cannot use Class.forName() since the class we want was loaded from a
-     * different ClassLoader.
-     */
-    @NonNull
-    public static Class<?> getClassInstance(@NonNull Object object, @NonNull String className) {
-        Class<?> superClass = object.getClass();
-        while (superClass != null) {
-            if (className.equals(superClass.getName())) {
-                return superClass;
-            }
-            superClass = superClass.getSuperclass();
-        }
-        throw new RuntimeException("invalid object/classname combination.");
-    }
-
-    /**
-     * Wraps all reflection related exceptions. Created since ReflectiveOperationException was
-     * introduced in 1.7 and we are still on 1.6
-     */
-    public static class ReflectionException extends Exception {
-        public ReflectionException() {
-            super();
-        }
-
-        public ReflectionException(String message) {
-            super(message);
-        }
-
-        public ReflectionException(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        public ReflectionException(Throwable cause) {
-            super(cause);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
deleted file mode 100644
index a2a8aa9..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.util;
-
-
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.GrowingArrayUtils;
-
-import android.util.SparseArray;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added
- * to it. When the array is compacted, not only deleted indices but also empty references
- * are removed, making the array efficient at removing references that were reclaimed.
- *
- * The code is taken from {@link SparseArray} directly and adapted to use weak references.
- *
- * Because our usage means that we never actually call {@link #remove(long)} or
- * {@link #delete(long)}, we must manually check if there are reclaimed references to
- * trigger an internal compact step (which is normally only triggered when an item is manually
- * removed).
- *
- * SparseArrays map integral values to Objects.  Unlike a normal array of Objects,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers (or Longs) to Objects.
- */
-@SuppressWarnings("unchecked")
-public class SparseWeakArray<E> {
-
-    private static final Object DELETED_REF = new Object();
-    private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF);
-    private boolean mGarbage = false;
-
-    /**
-     * Creates a new SparseArray containing no mappings.
-     */
-    public SparseWeakArray() {
-        this(10);
-    }
-
-    /**
-     * Creates a new SparseArray containing no mappings that will not
-     * require any additional memory allocation to store the specified
-     * number of mappings.
-     */
-    public SparseWeakArray(int initialCapacity) {
-        mKeys = ArrayUtils.newUnpaddedLongArray(initialCapacity);
-        mValues = new WeakReference[mKeys.length];
-        mSize = 0;
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or <code>null</code>
-     * if no such mapping has been made.
-     */
-    public E get(long key) {
-        return get(key, null);
-    }
-
-    /**
-     * Gets the Object mapped from the specified key, or the specified Object
-     * if no such mapping has been made.
-     */
-    public E get(long key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) {
-            return valueIfKeyNotFound;
-        } else {
-            return (E) mValues[i].get();
-        }
-    }
-
-    /**
-     * Removes the mapping from the specified key, if there was any.
-     */
-    public void delete(long key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            if (mValues[i] != DELETED) {
-                mValues[i] = DELETED;
-                mGarbage = true;
-            }
-        }
-    }
-
-    /**
-     * Alias for {@link #delete(long)}.
-     */
-    public void remove(long key) {
-        delete(key);
-    }
-
-    /**
-     * Removes the mapping at the specified index.
-     */
-    public void removeAt(int index) {
-        if (mValues[index] != DELETED) {
-            mValues[index] = DELETED;
-            mGarbage = true;
-        }
-    }
-
-    private void gc() {
-        int n = mSize;
-        int o = 0;
-        long[] keys = mKeys;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            WeakReference<?> val = values[i];
-
-            // Don't keep any non DELETED values, but only the one that still have a valid
-            // reference.
-            if (val != DELETED && val.get() != null) {
-                if (i != o) {
-                    keys[o] = keys[i];
-                    values[o] = val;
-                }
-
-                o++;
-            }
-        }
-
-        mGarbage = false;
-        mSize = o;
-    }
-
-    /**
-     * Adds a mapping from the specified key to the specified value,
-     * replacing the previous mapping from the specified key if there
-     * was one.
-     */
-    public void put(long key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
-
-        if (i >= 0) {
-            mValues[i] = new WeakReference(value);
-        } else {
-            i = ~i;
-
-            if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) {
-                mKeys[i] = key;
-                mValues[i] = new WeakReference(value);
-                return;
-            }
-
-            if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-                gc();
-
-                // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
-            }
-
-            mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
-            mValues = GrowingArrayUtils.insert(mValues, mSize, i, new WeakReference(value));
-            mSize++;
-        }
-    }
-
-    /**
-     * Returns the number of key-value mappings that this SparseArray
-     * currently stores.
-     */
-    public int size() {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mSize;
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the key from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public long keyAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return mKeys[index];
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, returns
-     * the value from the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public E valueAt(int index) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return (E) mValues[index].get();
-    }
-
-    /**
-     * Given an index in the range <code>0...size()-1</code>, sets a new
-     * value for the <code>index</code>th key-value mapping that this
-     * SparseArray stores.
-     */
-    public void setValueAt(int index, E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        mValues[index] = new WeakReference(value);
-    }
-
-    /**
-     * Returns the index for which {@link #keyAt} would return the
-     * specified key, or a negative number if the specified
-     * key is not mapped.
-     */
-    public int indexOfKey(long key) {
-        if (mGarbage) {
-            gc();
-        }
-
-        return binarySearch(mKeys, 0, mSize, key);
-    }
-
-    /**
-     * Returns an index for which {@link #valueAt} would return the
-     * specified key, or a negative number if no keys map to the
-     * specified value.
-     * Beware that this is a linear search, unlike lookups by key,
-     * and that multiple keys can map to the same value and this will
-     * find only one of them.
-     */
-    public int indexOfValue(E value) {
-        if (mGarbage) {
-            gc();
-        }
-
-        for (int i = 0; i < mSize; i++)
-            if (mValues[i].get() == value)
-                return i;
-
-        return -1;
-    }
-
-    /**
-     * Removes all key-value mappings from this SparseArray.
-     */
-    public void clear() {
-        int n = mSize;
-        WeakReference<?>[] values = mValues;
-
-        for (int i = 0; i < n; i++) {
-            values[i] = null;
-        }
-
-        mSize = 0;
-        mGarbage = false;
-    }
-
-    /**
-     * Puts a key/value pair into the array, optimizing for the case where
-     * the key is greater than all existing keys in the array.
-     */
-    public void append(long key, E value) {
-        if (mSize != 0 && key <= mKeys[mSize - 1]) {
-            put(key, value);
-            return;
-        }
-
-        if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
-            gc();
-        }
-
-        mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
-        mValues = GrowingArrayUtils.append(mValues, mSize, new WeakReference(value));
-        mSize++;
-    }
-
-    private boolean hasReclaimedRefs() {
-        for (int i = 0 ; i < mSize ; i++) {
-            if (mValues[i].get() == null) { // DELETED.get() never returns null.
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static int binarySearch(long[] a, int start, int len, long key) {
-        int high = start + len, low = start - 1, guess;
-
-        while (high - low > 1) {
-            guess = (high + low) / 2;
-
-            if (a[guess] < key)
-                low = guess;
-            else
-                high = guess;
-        }
-
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
-    }
-
-    private long[] mKeys;
-    private WeakReference<?>[] mValues;
-    private int mSize;
-}
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
deleted file mode 100644
index 6d013bb..0000000
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.maps;
-
-import com.android.layoutlib.bridge.MockView;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Mock version of the MapView.
- * Only non override public methods from the real MapView have been added in there.
- * Methods that take an unknown class as parameter or as return object, have been removed for now.
- * 
- * TODO: generate automatically.
- *
- */
-public class MapView extends MockView {
-
-    /**
-     * Construct a new WebView with a Context object.
-     * @param context A Context object used to access application assets.
-     */
-    public MapView(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     */
-    public MapView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.mapViewStyle);
-    }
-
-    /**
-     * Construct a new WebView with layout parameters and a default style.
-     * @param context A Context object used to access application assets.
-     * @param attrs An AttributeSet passed to our parent.
-     * @param defStyle The default style resource ID.
-     */
-    public MapView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-    
-    // START FAKE PUBLIC METHODS
-    
-    public void displayZoomControls(boolean takeFocus) {
-    }
-
-    public boolean canCoverCenter() {
-        return false;
-    }
-
-    public void preLoad() {
-    }
-
-    public int getZoomLevel() {
-        return 0;
-    }
-
-    public void setSatellite(boolean on) {
-    }
-
-    public boolean isSatellite() {
-        return false;
-    }
-
-    public void setTraffic(boolean on) {
-    }
-
-    public boolean isTraffic() {
-        return false;
-    }
-
-    public void setStreetView(boolean on) {
-    }
-
-    public boolean isStreetView() {
-        return false;
-    }
-
-    public int getLatitudeSpan() {
-        return 0;
-    }
-
-    public int getLongitudeSpan() {
-        return 0;
-    }
-
-    public int getMaxZoomLevel() {
-        return 0;
-    }
-
-    public void onSaveInstanceState(Bundle state) {
-    }
-
-    public void onRestoreInstanceState(Bundle state) {
-    }
-
-    public View getZoomControls() {
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java b/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
deleted file mode 100644
index 36efc3a..0000000
--- a/tools/layoutlib/bridge/src/dalvik/system/VMRuntime_Delegate.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.system;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate used to provide implementation of a select few native methods of {@link VMRuntime}
- * <p/>
- * Through the layoutlib_create tool, the original native methods of VMRuntime have been replaced
- * by calls to methods of the same name in this delegate class.
- */
-public class VMRuntime_Delegate {
-
-    // Copied from libcore/libdvm/src/main/java/dalvik/system/VMRuntime
-    @LayoutlibDelegate
-    /*package*/ static Object newUnpaddedArray(VMRuntime runtime, Class<?> componentType,
-            int minLength) {
-        // Dalvik has 32bit pointers, the array header is 16bytes plus 4bytes for dlmalloc,
-        // allocations are 8byte aligned so having 4bytes of array data avoids padding.
-        if (!componentType.isPrimitive()) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return java.lang.reflect.Array.newInstance(componentType, size);
-        } else if (componentType == char.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new char[size];
-        } else if (componentType == int.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new int[size];
-        } else if (componentType == byte.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new byte[size];
-        } else if (componentType == boolean.class) {
-            int bytes = 20 + minLength;
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes;
-            return new boolean[size];
-        } else if (componentType == short.class) {
-            int bytes = 20 + (2 * minLength);
-            int alignedUpBytes = (bytes + 7) & -8;
-            int dataBytes = alignedUpBytes - 20;
-            int size = dataBytes / 2;
-            return new short[size];
-        } else if (componentType == float.class) {
-            int size = ((minLength & 1) == 0) ? minLength + 1 : minLength;
-            return new float[size];
-        } else if (componentType == long.class) {
-            return new long[minLength];
-        } else if (componentType == double.class) {
-            return new double[minLength];
-        } else {
-            assert componentType == void.class;
-            throw new IllegalArgumentException("Can't allocate an array of void");
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
deleted file mode 100644
index 9c58010..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.icu;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.icu.text.DateTimePatternGenerator;
-import android.icu.util.Currency;
-import android.icu.util.ULocale;
-import android.icu.util.VersionInfo;
-
-import java.util.Locale;
-
-/**
- * Delegate implementing the native methods of libcore.icu.ICU
- *
- * Through the layoutlib_create tool, the original native methods of ICU have been replaced
- * by calls to methods of the same name in this delegate class.
- *
- */
-public class ICU_Delegate {
-
-    // --- Java delegates
-
-    @LayoutlibDelegate
-    /*package*/ static String toLowerCase(String s, String localeName) {
-        return s.toLowerCase();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String toUpperCase(String s, String localeName) {
-        return s.toUpperCase();
-    }
-
-    // --- Native methods accessing ICU's database.
-
-    @LayoutlibDelegate
-    /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) {
-        return DateTimePatternGenerator.getInstance(new ULocale(localeName))
-                .getBestPattern(skeleton);
-    }
-
-    @LayoutlibDelegate
-    @SuppressWarnings("deprecation")
-    /*package*/ static String getCldrVersion() {
-        return VersionInfo.ICU_DATA_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getIcuVersion() {
-        return VersionInfo.ICU_VERSION.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getUnicodeVersion() {
-        return VersionInfo.UNICODE_7_0.toString();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableBreakIteratorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCalendarLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCollatorLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableDateFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableNumberFormatLocalesNative() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getAvailableCurrencyCodes() {
-        return new String[0];
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyCode(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencyDisplayName(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyFractionDigits(String currencyCode) {
-        return 0;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static int getCurrencyNumericCode(String currencyCode) {
-        return Currency.getInstance(currencyCode).getNumericCode();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayCountryNative(String countryCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayLanguageNative(String languageCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayVariantNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDisplayScriptNative(String variantCode, String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Country(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getISO3Language(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String addLikelySubtags(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getScript(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOLanguagesNative() {
-        return Locale.getISOLanguages();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String[] getISOCountriesNative() {
-        return Locale.getISOCountries();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
-
-        // Used by Calendar.
-        result.firstDayOfWeek = 1;
-        result.minimalDaysInFirstWeek = 1;
-
-        // Used by DateFormatSymbols.
-        result.amPm = new String[] { "AM", "PM" };
-        result.eras = new String[] { "BC", "AD" };
-
-        result.longMonthNames = new String[] { "January", "February", "March", "April", "May",
-                "June", "July", "August", "September", "October", "November", "December" };
-        result.shortMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May",
-                "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-        result.longStandAloneMonthNames = result.longMonthNames;
-        result.shortStandAloneMonthNames = result.shortMonthNames;
-
-        // The platform code expects this to begin at index 1, rather than 0. It maps it directly to
-        // the constants from java.util.Calendar.<weekday>
-        result.longWeekdayNames = new String[] {
-                "", "Sunday", "Monday" ,"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
-        result.shortWeekdayNames = new String[] {
-                "", "Sun", "Mon" ,"Tue", "Wed", "Thu", "Fri", "Sat" };
-        result.tinyWeekdayNames = new String[] {
-                "", "S", "M", "T", "W", "T", "F", "S" };
-
-        result.longStandAloneWeekdayNames = result.longWeekdayNames;
-        result.shortStandAloneWeekdayNames = result.shortWeekdayNames;
-        result.tinyStandAloneWeekdayNames = result.tinyWeekdayNames;
-
-        result.fullTimeFormat = "";
-        result.longTimeFormat = "";
-        result.mediumTimeFormat = "";
-        result.shortTimeFormat = "";
-
-        result.fullDateFormat = "";
-        result.longDateFormat = "";
-        result.mediumDateFormat = "";
-        result.shortDateFormat = "";
-
-        // Used by DecimalFormatSymbols.
-        result.zeroDigit = '0';
-        result.decimalSeparator = '.';
-        result.groupingSeparator = ',';
-        result.patternSeparator = ' ';
-        result.percent = "%";
-        result.perMill = '\u2030';
-        result.monetarySeparator = ' ';
-        result.minusSign = "-";
-        result.exponentSeparator = "e";
-        result.infinity = "\u221E";
-        result.NaN = "NaN";
-        // Also used by Currency.
-        result.currencySymbol = "$";
-        result.internationalCurrencySymbol = "USD";
-
-        // Used by DecimalFormat and NumberFormat.
-        result.numberPattern = "%f";
-        result.integerPattern = "%d";
-        result.currencyPattern = "%s";
-        result.percentPattern = "%f";
-
-        return true;
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void setDefaultLocale(String locale) {
-        ICU.setDefaultLocale(locale);
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getDefaultLocale() {
-        return ICU.getDefaultLocale();
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static String getTZDataVersion() {
-        return ICU.getTZDataVersion();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java b/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
deleted file mode 100644
index 723d5c4..0000000
--- a/tools/layoutlib/bridge/src/libcore/io/MemoryMappedFile_Delegate.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.io;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.libcore.io.BridgeBufferIterator;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.system.ErrnoException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel.MapMode;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Delegate used to provide alternate implementation of select methods of {@link MemoryMappedFile}.
- */
-public class MemoryMappedFile_Delegate {
-
-    private static final DelegateManager<MemoryMappedFile_Delegate> sManager = new
-            DelegateManager<MemoryMappedFile_Delegate>(MemoryMappedFile_Delegate.class);
-
-    private static final Map<MemoryMappedFile, Long> sMemoryMappedFileMap =
-            new HashMap<MemoryMappedFile, Long>();
-
-    private final MappedByteBuffer mMappedByteBuffer;
-    private final long mSize;
-
-    /** Path on the target device where the data file is available. */
-    private static final String TARGET_PATH = System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo";
-    /** Path on the host (inside the SDK) where the data files are available. */
-    private static File sRootPath;
-
-    @LayoutlibDelegate
-    static MemoryMappedFile mmapRO(String path) throws ErrnoException {
-        if (!path.startsWith(TARGET_PATH)) {
-            throw new ErrnoException("Custom timezone data files are not supported.", 1);
-        }
-        if (sRootPath == null) {
-            throw new ErrnoException("Bridge has not been initialized properly.", 1);
-        }
-        path = path.substring(TARGET_PATH.length());
-        try {
-            File f = new File(sRootPath, path);
-            if (!f.exists()) {
-                throw new ErrnoException("File not found: " + f.getPath(), 1);
-            }
-            RandomAccessFile file = new RandomAccessFile(f, "r");
-            try {
-                long size = file.length();
-                MemoryMappedFile_Delegate newDelegate = new MemoryMappedFile_Delegate(file);
-                long filePointer = file.getFilePointer();
-                MemoryMappedFile mmFile = new MemoryMappedFile(filePointer, size);
-                long delegateIndex = sManager.addNewDelegate(newDelegate);
-                sMemoryMappedFileMap.put(mmFile, delegateIndex);
-                return mmFile;
-            } finally {
-                file.close();
-            }
-        } catch (IOException e) {
-            throw new ErrnoException("mmapRO", 1, e);
-        }
-    }
-
-    @LayoutlibDelegate
-    static void close(MemoryMappedFile thisFile) throws ErrnoException {
-        Long index = sMemoryMappedFileMap.get(thisFile);
-        if (index != null) {
-            sMemoryMappedFileMap.remove(thisFile);
-            sManager.removeJavaReferenceFor(index);
-        }
-    }
-
-    @LayoutlibDelegate
-    static BufferIterator bigEndianIterator(MemoryMappedFile file) {
-        MemoryMappedFile_Delegate delegate = getDelegate(file);
-        return new BridgeBufferIterator(delegate.mSize, delegate.mMappedByteBuffer.duplicate());
-    }
-
-    // TODO: implement littleEndianIterator()
-
-    public MemoryMappedFile_Delegate(RandomAccessFile file) throws IOException {
-        mSize = file.length();
-        // It's weird that map() takes size as long, but returns MappedByteBuffer which uses an int
-        // to store the marker to the position.
-        mMappedByteBuffer = file.getChannel().map(MapMode.READ_ONLY, 0, mSize);
-        assert mMappedByteBuffer.order() == ByteOrder.BIG_ENDIAN;
-    }
-
-    public static void setDataDir(File path) {
-        sRootPath = path;
-    }
-
-    private static MemoryMappedFile_Delegate getDelegate(MemoryMappedFile file) {
-        Long index = sMemoryMappedFileMap.get(file);
-        return index == null ? null : sManager.getDelegate(index);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
deleted file mode 100644
index 04fabc2..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/NativeAllocationRegistry_Delegate.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package libcore.util;
-
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-/**
- * Delegate implementing the native methods of {@link NativeAllocationRegistry}
- *
- * Through the layoutlib_create tool, the original native methods of NativeAllocationRegistry have
- * been replaced by calls to methods of the same name in this delegate class.
- *
- * This class behaves like the original native implementation, but in Java, keeping previously
- * native data into its own objects and mapping them to int that are sent back and forth between
- * it and the original NativeAllocationRegistry class.
- *
- * @see DelegateManager
- */
-public class NativeAllocationRegistry_Delegate {
-
-    // ---- delegate manager ----
-    private static final DelegateManager<NativeAllocationRegistry_Delegate> sManager =
-            new DelegateManager<>(NativeAllocationRegistry_Delegate.class);
-
-    private final FreeFunction mFinalizer;
-
-    private NativeAllocationRegistry_Delegate(FreeFunction finalizer) {
-        mFinalizer = finalizer;
-    }
-
-    /**
-     * The result of this method should be cached by the class and reused.
-     */
-    public static long createFinalizer(FreeFunction finalizer) {
-        return sManager.addNewDelegate(new NativeAllocationRegistry_Delegate(finalizer));
-    }
-
-    @LayoutlibDelegate
-    /*package*/ static void applyFreeFunction(long freeFunction, long nativePtr) {
-        // This method MIGHT run in the context of the finalizer thread. If the delegate method
-        // crashes, it could bring down the VM. That's why we catch all the exceptions and ignore
-        // them.
-        try {
-            NativeAllocationRegistry_Delegate delegate = sManager.getDelegate(freeFunction);
-            if (delegate != null) {
-                delegate.mFinalizer.free(nativePtr);
-            }
-        } catch (Throwable ignore) {
-        }
-    }
-
-    public interface FreeFunction {
-        void free(long nativePtr);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/.classpath b/tools/layoutlib/bridge/tests/.classpath
deleted file mode 100644
index 2b32e09..0000000
--- a/tools/layoutlib/bridge/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="res"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_bridge"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/bridge/tests/.project b/tools/layoutlib/bridge/tests/.project
deleted file mode 100644
index 2325eed..0000000
--- a/tools/layoutlib/bridge/tests/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_bridge-tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
deleted file mode 100644
index 1b65eee..0000000
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src) \
-	$(call all-java-files-under, res/testApp/MyApplication/src/main/myapplication.widgets)
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_MODULE := layoutlib-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib \
-			kxml2-2.3.0 \
-			layoutlib_api-prebuilt \
-			tools-common-prebuilt \
-			sdk-common \
-			junit-host \
-			guavalib \
-			mockito-host
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml b/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
deleted file mode 100644
index b8fc947..0000000
--- a/tools/layoutlib/bridge/tests/res/com/android/layoutlib/testdata/layout1.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-	android:orientation="vertical"
->
-	<Button
-		android:id="@+id/bouton"
-	    android:layout_width="wrap_content"
-	    android:layout_height="wrap_content"
-	    android:layout_weight="1"
-	    android:text="My Button Text"
-	    >
-	    </Button>
-	<View
-		android:id="@+id/surface"
-	    android:layout_width="match_parent"
-	    android:layout_height="match_parent"
-	    android:layout_weight="2"
-	    />
-	<TextView
-	    android:id="@+id/status"
-	    android:paddingLeft="2dip"
-	    android:layout_weight="0"
-	    android:background="@drawable/black"
-	    android:layout_width="match_parent"
-	    android:layout_height="wrap_content"
-	    android:lines="1"
-	    android:gravity="center_vertical|center_horizontal"
-	    android:text="My TextView Text"
-	    />
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/empty.xml b/tools/layoutlib/bridge/tests/res/empty.xml
deleted file mode 100644
index e69de29..0000000
--- a/tools/layoutlib/bridge/tests/res/empty.xml
+++ /dev/null
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
deleted file mode 100644
index a2ce0dc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-.gradle
-local.properties
-.idea
-.DS_Store
-*.iml
-# We need the built .class files to load custom views and R class.
-# The only way to negate an exclusion is by including every single parent
-# and excluding all children of those parents.
-
-/build/*
-!/build/intermediates/
-
-/build/intermediates/*
-!/build/intermediates/classes/
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
deleted file mode 100644
index 4781660..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build.gradle
+++ /dev/null
@@ -1,48 +0,0 @@
-buildscript {
-    repositories {
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-    }
-}
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 25
-    buildToolsVersion '25.0.0'
-    defaultConfig {
-        applicationId 'com.android.layoutlib.test.myapplication'
-        minSdkVersion 21
-        targetSdkVersion 25
-        versionCode 1
-        versionName '1.0'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-    lintOptions {
-        abortOnError false
-    }
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_6
-        targetCompatibility JavaVersion.VERSION_1_6
-    }
-}
-
-dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
deleted file mode 100644
index 1ca7e01..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/androidTest/debug/com/android/layoutlib/test/myapplication/test/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
deleted file mode 100644
index f73528a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/ArraysCheckWidget.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
deleted file mode 100644
index ceb56bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/BuildConfig.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
deleted file mode 100644
index 5bb04fc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/MyActivity.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
deleted file mode 100644
index b87f193..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$array.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
deleted file mode 100644
index e2968d40..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$attr.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
deleted file mode 100644
index ff699d1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$color.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
deleted file mode 100644
index a3931b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$dimen.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
deleted file mode 100644
index e293677..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$drawable.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
deleted file mode 100644
index d6268bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$id.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
deleted file mode 100644
index 08b98fb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$integer.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
deleted file mode 100644
index f9be1ca..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
deleted file mode 100644
index 6874b49e..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$menu.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
deleted file mode 100644
index a4205a8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$string.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
deleted file mode 100644
index 4fb3b61..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$style.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
deleted file mode 100644
index dba67fd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
deleted file mode 100644
index affc31e..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
deleted file mode 100644
index 7014ddb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
deleted file mode 100644
index bd78353..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
deleted file mode 100644
index 88fa9dd..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
deleted file mode 100644
index e33f92d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
deleted file mode 100644
index 915868c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
deleted file mode 100644
index ee72a6f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
deleted file mode 100644
index 781d617..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
deleted file mode 100644
index 5b64d33..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
deleted file mode 100644
index 736b287..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/font_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
deleted file mode 100644
index a8567b3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
deleted file mode 100644
index 5ae95ea3..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
deleted file mode 100644
index b2b6a97..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
deleted file mode 100644
index cf1a769..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
deleted file mode 100644
index 67355b8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
deleted file mode 100644
index e0abcf4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
deleted file mode 100644
index 3d0fbd6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
deleted file mode 100644
index 86b00415..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
deleted file mode 100644
index 7bbae09..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
deleted file mode 100644
index e9dca692..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
deleted file mode 100644
index 5d08ba7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Settings specified in this file will override any Gradle settings
-# configured through the IDE.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 8c0fb64..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 3b51ffe..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-#Tue Mar 17 15:13:06 PDT 2015
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
deleted file mode 100755
index 91a7e26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
-    echo "$*"
-}
-
-die ( ) {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
deleted file mode 100644
index aec9973..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/gradlew.bat
+++ /dev/null
@@ -1,90 +0,0 @@
-@if "%DEBUG%" == "" @echo off

-@rem ##########################################################################

-@rem

-@rem  Gradle startup script for Windows

-@rem

-@rem ##########################################################################

-

-@rem Set local scope for the variables with windows NT shell

-if "%OS%"=="Windows_NT" setlocal

-

-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

-set DEFAULT_JVM_OPTS=

-

-set DIRNAME=%~dp0

-if "%DIRNAME%" == "" set DIRNAME=.

-set APP_BASE_NAME=%~n0

-set APP_HOME=%DIRNAME%

-

-@rem Find java.exe

-if defined JAVA_HOME goto findJavaFromJavaHome

-

-set JAVA_EXE=java.exe

-%JAVA_EXE% -version >NUL 2>&1

-if "%ERRORLEVEL%" == "0" goto init

-

-echo.

-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

-

-goto fail

-

-:findJavaFromJavaHome

-set JAVA_HOME=%JAVA_HOME:"=%

-set JAVA_EXE=%JAVA_HOME%/bin/java.exe

-

-if exist "%JAVA_EXE%" goto init

-

-echo.

-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

-

-goto fail

-

-:init

-@rem Get command-line arguments, handling Windowz variants

-

-if not "%OS%" == "Windows_NT" goto win9xME_args

-if "%@eval[2+2]" == "4" goto 4NT_args

-

-:win9xME_args

-@rem Slurp the command line arguments.

-set CMD_LINE_ARGS=

-set _SKIP=2

-

-:win9xME_args_slurp

-if "x%~1" == "x" goto execute

-

-set CMD_LINE_ARGS=%*

-goto execute

-

-:4NT_args

-@rem Get arguments from the 4NT Shell from JP Software

-set CMD_LINE_ARGS=%$

-

-:execute

-@rem Setup the command line

-

-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

-

-@rem Execute Gradle

-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

-

-:end

-@rem End local scope for the variables with windows NT shell

-if "%ERRORLEVEL%"=="0" goto mainEnd

-

-:fail

-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

-rem the _cmd.exe /c_ return code!

-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

-exit /b 1

-

-:mainEnd

-if "%OS%"=="Windows_NT" endlocal

-

-:omega

diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
deleted file mode 100644
index b0fcd2d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /usr/local/google/home/deepanshu/ssd/sdk_out/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
deleted file mode 100644
index 2067474..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.layoutlib.test.myapplication" >
-<!-- If changing package here, update LayoutLibCallBack in tests. -->
-    <application
-        android:allowBackup="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name="com.android.layoutlib.test.myapplication.MyActivity"
-            android:label="@string/app_name" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
deleted file mode 100644
index e7f22bf..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/ArraysCheckWidget.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.test.myapplication;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-/**
- * A widget to test obtaining arrays from resources.
- */
-public class ArraysCheckWidget extends LinearLayout {
-    public ArraysCheckWidget(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public ArraysCheckWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        Resources resources = context.getResources();
-        for (CharSequence chars : resources.getTextArray(R.array.array)) {
-            addTextView(context, chars);
-        }
-        for (int i : resources.getIntArray(R.array.int_array)) {
-            addTextView(context, String.valueOf(i));
-        }
-        for (String string : resources.getStringArray(R.array.string_array)) {
-            addTextView(context, string);
-        }
-    }
-
-    private void addTextView(Context context, CharSequence string) {
-        TextView textView = new TextView(context);
-        textView.setText(string);
-        textView.setTextSize(30);
-        addView(textView);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
deleted file mode 100644
index 59de457..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/java/com/android/layoutlib/test/myapplication/MyActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.android.layoutlib.test.myapplication;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-
-public class MyActivity extends Activity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity);
-    }
-
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // Inflate the menu; this adds items to the action bar if it is present.
-        getMenuInflater().inflate(R.menu.my, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        // Handle action bar item clicks here. The action bar will
-        // automatically handle clicks on the Home/Up button, so long
-        // as you specify a parent activity in AndroidManifest.xml.
-        int id = item.getItemId();
-        if (id == R.id.action_settings) {
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
deleted file mode 100644
index 3b819e5..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomCalendar.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CalendarView;
-
-public class CustomCalendar extends CalendarView {
-    public CustomCalendar(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomCalendar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        setDate(871732800000L, false, true);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
deleted file mode 100644
index f3877f1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/CustomDate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.DatePicker;
-
-public class CustomDate extends DatePicker {
-    public CustomDate(Context context) {
-        super(context);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init();
-    }
-
-    public CustomDate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        init();
-    }
-
-    private void init() {
-        init(2015, 0, 20, null);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
deleted file mode 100644
index 36e5c26..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/InsetsWidget.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.test.myapplication.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.WindowInsets;
-import android.widget.TextView;
-
-public class InsetsWidget extends TextView {
-    public static boolean sApplyInsetsCalled = false;
-
-    public InsetsWidget(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        requestApplyInsets();
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        sApplyInsetsCalled = true;
-        return super.onApplyWindowInsets(insets);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
deleted file mode 100644
index 58ad46d..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/myapplication.widgets/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * This package contains custom widgets used to set a specific time for the DayTimePicker during
- * testing.
- * The classes here are both used from the Android project and from the Bridge test project.
- */
-package com.android.layoutlib.test.myapplication.widgets;
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
deleted file mode 100644
index fc0afa6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-
-<gradient xmlns:android="http://schemas.android.com/apk/res/android"
-          android:startX="10"
-          android:startY="10"
-          android:endX="50"
-          android:endY="50"
-          android:startColor="#ffff0000"
-          android:endColor="#ff00ff00" />
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
deleted file mode 100644
index 8f862c8..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@android:color/red" />
-    <foreground android:drawable="@drawable/headset" />
-</adaptive-icon>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
deleted file mode 100644
index 42e3beb..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/android.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:viewportWidth="1102"
-        android:viewportHeight="642"
-        android:width="1102px"
-        android:height="642px">
-
-    <group
-        android:translateX="-126.347"
-        android:translateY="6.7928655e-4">
-
-
-        <path
-            android:fillColor="#94c147"
-            android:pathData="
-            m 552.777,147.57
-            c -14.147,0 -25.622,11.652 -25.622,26.02
-            v 101.68
-            c 0,14.372 11.475,26.019 25.622,26.019 14.147,0 25.61,-11.646 25.61,-26.019
-            V 173.59
-            c 0.001,-14.368 -11.462,-26.02 -25.61,-26.02
-            z
-
-            m -309.011,0
-            c -14.155,0 -25.618,11.652 -25.618,26.02
-            v 101.68
-            c 0,14.372 11.462,26.019 25.618,26.019 14.153,0 25.623,-11.646 25.623,-26.019
-            V 173.59
-            c -0.008,-14.368 -11.475,-26.02 -25.623,-26.02
-            z" />
-
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 284.799,148.364 v 185.768 c 0,11.035 8.948,19.98 19.983,19.98 h 22.815 v 56.567 c 0,14.37 11.47,26.016 25.623,26.016 14.148,0 25.623,-11.646 25.623,-26.016 v -56.567 h 39.878 v 56.567 c 0,14.37 11.463,26.016 25.61,26.016 14.147,0 25.622,-11.646 25.622,-26.016 v -56.567 h 22.828 c 11.022,0 19.971,-8.953 19.971,-19.98 V 148.364 H 284.799 l 0,0 z" />
-
-        <group
-        android:name="head"
-        android:pivotX="400"
-        android:pivotY="131.105">
-
-        <path
-        android:fillColor="#94c147"
-        android:pathData="m 452.302,52.105 21.057,-30.572 c 1.245,-1.819 0.939,-4.199 -0.695,-5.329 -1.637,-1.123 -3.968,-0.568 -5.225,1.251 l -21.875,31.75 c -14.404,-5.682 -30.418,-8.844 -47.293,-8.844 -16.87,0 -32.893,3.162 -47.297,8.844 l -21.875,-31.75 c -1.257,-1.819 -3.589,-2.375 -5.225,-1.251 -1.636,1.124 -1.946,3.509 -0.696,5.329 l 21.057,30.572 c -33.464,15.57 -56.951,45.166 -59.941,79.706 H 512.25 C 509.259,97.271 485.772,67.676 452.302,52.105 z M 350.187,100.28 c -6.965,0 -12.617,-5.646 -12.617,-12.616 0,-6.958 5.647,-12.61 12.617,-12.61 6.97,0 12.603,5.652 12.603,12.61 0,6.965 -5.64,12.616 -12.603,12.616 z m 97.744,0 c -6.97,0 -12.609,-5.646 -12.609,-12.616 0,-6.958 5.64,-12.61 12.609,-12.61 6.971,0 12.61,5.652 12.61,12.61 0,6.965 -5.64,12.616 -12.61,12.616 z" />
-        </group>
-
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
deleted file mode 100644
index 897c411..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/headset.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  ~ Copyright (C) 2016 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="150dp"
-        android:height="150dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="m12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h4v1h-7v2h6c1.66,0 3,-1.34 3,-3V10c0,-4.97 -4.03,-9 -9,-9z"/>
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
deleted file mode 100644
index 67481d4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/ic_launcher.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="#ff0000" />
-    <size
-        android:width="20dp"
-        android:height="20dp" />
-</shape>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
deleted file mode 100644
index 0998b25..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="76dp"
-        android:width="76dp"
-        android:viewportHeight="48"
-        android:viewportWidth="48"
-        android:alpha="0.6">
-
-    <group
-        android:name="root"
-        android:translateX="24.0"
-        android:translateY="24.0">
-        <!--
-            This is the same as the material indeterminate progressbar which involves drawing
-            several cubic segments
-        -->
-        <path
-            android:pathData="M0, 0 m 0, -19 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#00FF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.8"
-            android:trimPathStart="0.3" />
-        <!-- Same figure with reversed end and start -->
-        <path
-            android:pathData="M0, 0 m 0, -12 a 19,19 0 1,1 0,38 a 19,19 0 1,1 0,-38"
-            android:strokeColor="#FFFF00"
-            android:strokeLineCap="square"
-            android:strokeLineJoin="miter"
-            android:strokeWidth="1"
-            android:trimPathEnd="0.3"
-            android:trimPathStart="0.8" />
-
-        <!--
-            Draw a few partial quadratic segments
-        -->
-        <path
-            android:strokeWidth="2"
-            android:strokeColor="#FFFF00"
-            android:pathData="M2,2 Q 5 30 15 0"
-            android:trimPathStart="0.1"
-            android:trimPathEnd="0.9"
-        />
-
-        <!--
-            Draw a line
-        -->
-        <path
-            android:strokeWidth="3"
-            android:strokeColor="#00FFFF"
-            android:pathData="M-10,-10 L 10, 10"
-            android:trimPathStart="0.2"
-            android:trimPathEnd="0.8"
-        />
-
-        <!--
-            Draw a line with gradient stroke color
-        -->
-        <path
-            android:strokeWidth="1"
-            android:strokeColor="#FF00FF"
-            android:fillColor="@color/gradient"
-            android:pathData="M-20,-20 l0, 10 l10, 0 l0, -10 l-10,0 "
-        />
-
-        <!--
-            Draw squares with different fill types
-        -->
-        <path
-            android:fillType="evenOdd"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#AAEFCC"
-            android:pathData="M-20,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-
-        <path
-            android:fillType="nonZero"
-            android:strokeWidth="1"
-            android:strokeColor="#AABBCC"
-            android:fillColor="#40AAEFCC"
-            android:pathData="M0,-40 l0, 10 l10, 0 l0, -10 l-10,0 m5,0 l0, 10 l10, 0 l0, -10 l-10,0"
-        />
-    </group>
-
-</vector>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
deleted file mode 100644
index b1e9206..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfamily.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<font-family xmlns:android="http://schemas.android.com/apk/res/android">
-    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/testfont" />
-    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/testfont2" />
-</font-family>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont.ttf b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont.ttf
deleted file mode 100644
index 2852302..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont2.ttf b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont2.ttf
deleted file mode 100644
index b7bf5b4..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/font/testfont2.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
deleted file mode 100644
index 97d1983..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/activity.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:paddingLeft="@dimen/activity_horizontal_margin"
-    android:paddingRight="@dimen/activity_horizontal_margin"
-    android:paddingTop="@dimen/activity_vertical_margin"
-    android:paddingBottom="@dimen/activity_vertical_margin"
-    tools:context=".MyActivity">
-
-    <TextView
-        android:text="@string/hello_world"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/text1"/>
-
-    <include layout="@layout/layout"
-        android:layout_below="@+id/text1"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content" />
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
deleted file mode 100644
index 456b5f6..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml
+++ /dev/null
@@ -1,403 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:ignore="HardcodedText,LabelFor,TextFields,ContentDescription,RtlHardcoded">
-
-    <FrameLayout
-        android:id="@id/frameLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginEnd="311dp">
-
-        <TextView
-            android:id="@id/textView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="left|top"
-            android:text="New Text" />
-    </FrameLayout>
-
-    <TextView
-        android:id="@id/textView2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/frameLayout"
-        android:text="Large Text"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:pointerIcon="hand" />
-
-    <TextView
-        android:id="@id/textView3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Medium Text"
-        android:textAppearance="?android:attr/textAppearanceMedium" />
-
-    <TextView
-        android:id="@id/textView4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/textView2"
-        android:layout_toEndOf="@id/textView2"
-        android:text="Small Text"
-        android:textAppearance="?android:attr/textAppearanceSmall" />
-
-    <Button
-        android:id="@id/button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/textView3"
-        android:layout_toEndOf="@id/textView4"
-        android:text="New Button" />
-
-    <Button
-        android:id="@id/button2"
-        style="?android:attr/buttonStyleSmall"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_toEndOf="@id/button"
-        android:text="New Button" />
-
-    <CheckBox
-        android:id="@id/checkBox"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignEnd="@id/button"
-        android:layout_below="@id/button"
-        android:text="New CheckBox" />
-
-    <Switch
-        android:id="@id/switch1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/textView2"
-        android:text="New Switch" />
-
-    <ImageButton
-        android:id="@id/imageButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/switch1" />
-
-    <ImageView
-        android:id="@id/imageView"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_launcher"
-        android:layout_below="@id/button"
-        android:layout_toEndOf="@id/imageButton" />
-
-    <GridLayout
-        android:id="@id/gridLayout"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/imageButton"
-        android:columnCount="2"
-        android:rowCount="2">
-
-        <ProgressBar
-            android:id="@id/progressBar"
-            style="?android:attr/progressBarStyleLarge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="0" />
-
-        <ProgressBar
-            android:id="@id/progressBar3"
-            style="?android:attr/progressBarStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="0"
-            android:layout_row="1" />
-
-        <ProgressBar
-            android:id="@id/progressBar4"
-            style="?android:attr/progressBarStyleHorizontal"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_column="1"
-            android:layout_row="1" />
-    </GridLayout>
-
-    <SeekBar
-        android:id="@id/seekBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/gridLayout"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <RatingBar
-        android:id="@id/ratingBar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/switch2"
-        android:layout_toEndOf="@id/gridLayout" />
-
-    <Switch
-        android:id="@id/switch2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/seekBar"
-        android:layout_toEndOf="@id/switch1"
-        android:checked="true" />
-
-    <EditText
-        android:id="@id/editText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBottom="@id/ratingBar"
-        android:layout_alignParentStart="true"
-        android:text="plain text" />
-
-    <EditText
-        android:id="@id/editText2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/ratingBar"
-        android:ems="3"
-        android:inputType="textPersonName"
-        android:text="Name" />
-
-    <EditText
-        android:id="@id/editText3"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
-        android:layout_toEndOf="@id/editText2"
-        android:ems="2"
-        android:inputType="textPassword"
-        android:text="password" />
-
-    <EditText
-        android:id="@id/editText4"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText3"
-        android:layout_toEndOf="@id/editText3"
-        android:ems="3"
-        android:inputType="numberPassword"
-        android:text="numeric password" />
-
-    <ToggleButton
-        android:id="@+id/toggleButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignTop="@id/editText4"
-        android:layout_toEndOf="@id/editText4"
-        android:text="New ToggleButton" />
-
-    <EditText
-        android:id="@id/editText5"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText3"
-        android:layout_toStartOf="@id/editText6"
-        android:ems="7"
-        android:inputType="textEmailAddress"
-        android:text="email@domain.com" />
-
-    <EditText
-        android:id="@id/editText6"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_below="@id/editText4"
-        android:ems="7"
-        android:inputType="phone"
-        android:text="+11235554344" />
-
-    <EditText
-        android:id="@id/editText7"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText"
-        android:layout_toEndOf="@id/editText4"
-        android:ems="10"
-        android:inputType="textPostalAddress"
-        android:text="1600 Amphitheatre" />
-
-    <EditText
-        android:id="@id/editText9"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_alignParentStart="true"
-        android:ems="3"
-        android:inputType="time"
-        android:text="12:12" />
-
-    <RadioGroup
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/editText5"
-        android:layout_toEndOf="@id/editText9"
-        android:orientation="horizontal">
-
-        <RadioButton
-            android:id="@id/radioButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton" />
-
-        <RadioButton
-            android:id="@id/radioButton2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="New RadioButton"
-            android:checked="true" />
-
-    </RadioGroup>
-
-    <CheckedTextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CheckedTextView"
-        android:id="@id/checkedTextView"
-        android:layout_below="@id/button2"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/button2" />
-
-    <DialerFilter
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/checkBox"
-        android:layout_toStartOf="@id/quickContactBadge"
-        android:id="@id/dialerFilter"
-        android:layout_above="@id/ratingBar"
-        android:layout_toEndOf="@id/seekBar">
-
-        <EditText
-            android:id="@android:id/hint"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="Hint" />
-
-        <EditText
-            android:id="@android:id/primary"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/hint"
-            android:text="Primary" />
-    </DialerFilter>
-
-    <QuickContactBadge
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/quickContactBadge"
-        android:layout_below="@id/checkedTextView"
-        android:layout_alignParentEnd="true" />
-
-    <android.inputmethodservice.ExtractEditText
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="ExtractEditText"
-        android:id="@id/extractEditText"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/checkedTextView" />
-
-    <ZoomControls
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/zoomControls"
-        android:layout_below="@id/editText9"
-        android:layout_alignParentStart="true" />
-
-    <TextureView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/textureView"
-        android:layout_below="@id/zoomControls"
-        android:layout_alignParentStart="true"
-        android:layout_alignBottom="@id/extractEditText"
-        android:layout_toStartOf="@id/editText3" />
-
-    <ListView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/listView"
-        android:layout_below="@id/textureView"
-        android:layout_alignParentStart="true"
-        android:layout_alignEnd="@id/textureView" />
-
-    <GridView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/gridView"
-        android:layout_below="@id/extractEditText"
-        android:layout_alignParentEnd="true"
-        android:layout_alignStart="@id/extractEditText" />
-
-    <ScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/scrollView"
-        android:layout_below="@id/zoomControls"
-        android:layout_toRightOf="@id/listView"
-        android:layout_toLeftOf="@id/extractEditText">
-
-    <TabHost
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:id="@id/tabHost">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical">
-
-            <TabWidget
-                android:id="@android:id/tabs"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
-
-            <FrameLayout
-                android:id="@android:id/tabcontent"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-                <LinearLayout
-                    android:id="@id/linearLayout"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-                <LinearLayout
-                    android:id="@id/linearLayout2"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:orientation="vertical"/>
-
-            </FrameLayout>
-        </LinearLayout>
-    </TabHost>
-</ScrollView>
-
-    <SearchView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@id/searchView"
-        android:layout_alignBottom="@id/zoomControls"
-        android:layout_toEndOf="@id/seekBar" />
-
-</RelativeLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
deleted file mode 100644
index e9aa9e1..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/array_check.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.layoutlib.test.myapplication.ArraysCheckWidget
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-</com.android.layoutlib.test.myapplication.ArraysCheckWidget>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
deleted file mode 100644
index 2c66b7f..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="horizontal"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
deleted file mode 100644
index a255da7..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <TextView
-        android:background="#FF0000"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FF00"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#0000FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#FF00FF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-    <TextView
-        android:background="#00FFFF"
-        android:textSize="200sp"
-        android:layout_width="200dp"
-        android:layout_height="200dp" />
-</merge>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
deleted file mode 100644
index 5319654..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:padding="16dp"
-              android:orientation="vertical"
-              android:background="#AAAAAA"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content">
-
-    <include layout="@layout/expand_layout"
-             android:layout_height="wrap_content"
-             android:layout_width="wrap_content" />
-
-</LinearLayout>
-
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
deleted file mode 100644
index c63b211..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/fonts_test.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED"
-        android:textSize="50sp"
-        android:fontFamily="sans-serif-condensed"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="CONDENSED ITALIC"
-        android:textSize="30sp"
-        android:fontFamily="sans-serif-condensed"
-        android:textStyle="italic"
-        />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="MONOSPACE"
-        android:textSize="50sp"
-        android:fontFamily="monospace"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfont"/>
-
-    <Space
-        android:layout_width="wrap_content"
-        android:layout_height="30dp" />
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"/>
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Custom family"
-        android:textSize="20sp"
-        android:fontFamily="@font/testfamily"
-        android:textStyle="italic"/>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
deleted file mode 100644
index c42284a..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/four_corners.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Bottom Text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true"
-        android:textSize="40sp"
-        android:text="Top text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="Start text" />
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"
-        android:textSize="40sp"
-        android:text="End text" />
-</RelativeLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
deleted file mode 100644
index ff14ce0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/layout.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:columnCount="2"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Some text"/>
-    <Switch
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:checked="true"
-        android:layout_gravity="center"
-        />
-    <com.android.layoutlib.test.myapplication.widgets.CustomDate
-        android:layout_width="100dp"
-        android:layout_height="wrap_content"/>
-    <com.android.layoutlib.test.myapplication.widgets.CustomCalendar
-        android:layout_width="200dp"
-        android:layout_gravity="center_horizontal"
-        android:layout_height="200dp"/>
-</GridLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
deleted file mode 100644
index a07498c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical"
-              android:scrollX="30px"
-              android:scrollY="90px">
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#FF0000" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#00FF00" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#0000FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:background="#FF00FF" />
-    <LinearLayout
-        android:layout_width="60dp"
-        android:layout_height="60dp"
-        android:background="#00FFFF" />
-
-    <LinearLayout
-        android:layout_width="200dp"
-        android:layout_height="400dp"
-        android:orientation="vertical"
-        android:scrollX="-90px"
-        android:scrollY="450px">
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#FF0000" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#00FF00" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#0000FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="30dp"
-            android:background="#FF00FF" />
-        <LinearLayout
-            android:layout_width="fill_parent"
-            android:layout_height="60dp"
-            android:background="#00FFFF" />
-    </LinearLayout>
-
-
-</LinearLayout>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
deleted file mode 100644
index b1d6a60..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent" >
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="48dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="0dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1">
-
-        <Button
-            android:layout_marginLeft="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentLeft="true"
-            android:layout_centerVertical="true"
-            android:elevation="12dp"
-            android:stateListAnimator="@null"/>
-
-        <Button
-            android:layout_marginRight="40dp"
-            android:layout_width="48dp"
-            android:layout_height="40dp"
-            android:layout_alignParentRight="true"
-            android:layout_centerVertical="true"
-            android:elevation="108dp"
-            android:stateListAnimator="@null"/>
-
-    </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
deleted file mode 100644
index bea58cc..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/menu/my.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context=".MyActivity" >
-    <item android:id="@+id/action_settings"
-        android:title="@string/action_settings"
-        android:orderInCategory="100"
-        android:showAsAction="never" />
-</menu>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
deleted file mode 100644
index 5f58d39..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/arrays.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <array name="array">
-        <item>first</item>
-        <item>second</item>
-    </array>
-    <integer-array name="int_array">
-        <item>1</item>
-        <item>0xaB</item>  <!-- hex entry (decimal 171) -->
-        <item>010</item>   <!-- octal entry -->
-        <item>@integer/ten</item>  <!-- value reference -->
-        <item>?attr/myattr</item>  <!-- theme attr reference -->
-    </integer-array>
-    <string-array name="string_array">
-        <item>mystring</item>
-        <item>@string/hello_world</item>   <!-- string ref in appNs -->
-        <!-- theme ref in android NS. value = @string/candidates_style = <u>candidates</u> -->
-        <item>?android:attr/candidatesTextStyleSpans</item>
-        <item>@android:string/unknownName</item>  <!-- value = Unknown -->
-        <item>?EC</item>
-    </string-array>
-
-    <!-- resources that the above array can refer to -->
-    <integer name="ten">10</integer>
-    <integer name="twelve">12</integer>
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
deleted file mode 100644
index 894e18c..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <attr name="myattr" format="integer" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
deleted file mode 100644
index 47c8224..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
deleted file mode 100644
index 1dc2fa0..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/ids.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <item type="id" name="button" />
-    <item type="id" name="button2" />
-    <item type="id" name="checkBox" />
-    <item type="id" name="checkedTextView" />
-    <item type="id" name="dialerFilter" />
-    <item type="id" name="editText" />
-    <item type="id" name="editText2" />
-    <item type="id" name="editText3" />
-    <item type="id" name="editText4" />
-    <item type="id" name="editText5" />
-    <item type="id" name="editText6" />
-    <item type="id" name="editText7" />
-    <item type="id" name="editText8" />
-    <item type="id" name="editText9" />
-    <item type="id" name="extractEditText" />
-    <item type="id" name="frameLayout" />
-    <item type="id" name="gridLayout" />
-    <item type="id" name="gridView" />
-    <item type="id" name="imageButton" />
-    <item type="id" name="imageView" />
-    <item type="id" name="linearLayout" />
-    <item type="id" name="linearLayout2" />
-    <item type="id" name="listView" />
-    <item type="id" name="progressBar" />
-    <item type="id" name="progressBar2" />
-    <item type="id" name="progressBar3" />
-    <item type="id" name="progressBar4" />
-    <item type="id" name="quickContactBadge" />
-    <item type="id" name="radioButton" />
-    <item type="id" name="radioButton2" />
-    <item type="id" name="ratingBar" />
-    <item type="id" name="scrollView" />
-    <item type="id" name="searchView" />
-    <item type="id" name="seekBar" />
-    <item type="id" name="spinner" />
-    <item type="id" name="switch1" />
-    <item type="id" name="switch2" />
-    <item type="id" name="tabHost" />
-    <item type="id" name="textView" />
-    <item type="id" name="textView2" />
-    <item type="id" name="textView3" />
-    <item type="id" name="textView4" />
-    <item type="id" name="textureView" />
-    <item type="id" name="zoomControls" />
-</resources>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
deleted file mode 100644
index 2b7083b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">My Application</string>
-    <string name="hello_world">Hello world!</string>
-    <string name="action_settings">Settings</string>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
deleted file mode 100644
index debe33b..0000000
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<resources>
-
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
-        <item name="myattr">@integer/ten</item>
-    </style>
-
-</resources>
diff --git a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java b/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
deleted file mode 100644
index 4f1c16c..0000000
--- a/tools/layoutlib/bridge/tests/src/android/app/SystemServiceRegistry_AccessorTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import org.junit.Test;
-
-import android.content.Context;
-import android.hardware.input.InputManager;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager;
-
-import static org.junit.Assert.*;
-
-public class SystemServiceRegistry_AccessorTest {
-    @Test
-    public void testRegistry() {
-        // Just check a few services to make sure we don't break the accessor
-        assertEquals(Context.ACCESSIBILITY_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(AccessibilityManager.class));
-        assertEquals(Context.INPUT_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(InputManager.class));
-        assertEquals(Context.WINDOW_SERVICE,
-                SystemServiceRegistry_Accessor.getSystemServiceName(WindowManager.class));
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java b/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
deleted file mode 100644
index d20fb14..0000000
--- a/tools/layoutlib/bridge/tests/src/android/graphics/Matrix_DelegateTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import junit.framework.TestCase;
-
-/**
- *
- */
-public class Matrix_DelegateTest extends TestCase {
-
-    public void testIdentity() {
-        Matrix m1 = new Matrix();
-
-        assertTrue(m1.isIdentity());
-
-        m1.setValues(new float[] { 1,0,0, 0,1,0, 0,0,1 });
-        assertTrue(m1.isIdentity());
-    }
-
-    public void testCopyConstructor() {
-        Matrix m1 = new Matrix();
-        Matrix m2 = new Matrix(m1);
-
-        float[] v1 = new float[9];
-        float[] v2 = new float[9];
-        m1.getValues(v1);
-        m2.getValues(v2);
-
-        for (int i = 0 ; i < 9; i++) {
-            assertEquals(v1[i], v2[i]);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java b/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
deleted file mode 100644
index 2fcec8e..0000000
--- a/tools/layoutlib/bridge/tests/src/android/util/BridgeXmlPullAttributesTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.BridgeContext;
-
-import org.junit.Test;
-import org.xmlpull.v1.XmlPullParser;
-
-import com.google.common.collect.ImmutableMap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class BridgeXmlPullAttributesTest {
-    @Test
-    public void testGetAttributeIntValueForEnums() {
-        RenderResources renderResources = new RenderResources();
-
-        XmlPullParser parser = mock(XmlPullParser.class);
-        when(parser.getAttributeValue(BridgeConstants.NS_RESOURCES, "layout_width"))
-                .thenReturn("match_parent");
-        when(parser.getAttributeName(0)).thenReturn("layout_width");
-        when(parser.getAttributeNamespace(0)).thenReturn(BridgeConstants.NS_RESOURCES);
-        // Return every value twice since there is one test using name and other using index
-        when(parser.getAttributeValue("http://custom", "my_custom_attr"))
-                .thenReturn("a", "a", "b", "b", "invalid", "invalid");
-        when(parser.getAttributeName(1)).thenReturn("my_custom_attr");
-        when(parser.getAttributeNamespace(1)).thenReturn("http://custom");
-
-        BridgeContext context = mock(BridgeContext.class);
-        when(context.getRenderResources()).thenReturn(renderResources);
-
-        BridgeXmlPullAttributes attributes = new BridgeXmlPullAttributes(
-                parser,
-                context,
-                false,
-                attrName -> {
-                    if ("layout_width".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "match_parent", 123);
-                    }
-                    return ImmutableMap.of();
-                },
-                attrName -> {
-                    if ("my_custom_attr".equals(attrName)) {
-                        return ImmutableMap.of(
-                                "a", 1,
-                                "b", 2
-                        );
-                    }
-                    return ImmutableMap.of();
-                });
-
-        // Test a framework defined enum attribute
-        assertEquals(123, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_width", 500));
-        assertEquals(123, attributes.getAttributeIntValue(0, 500));
-        // Test non existing attribute (it should return the default value)
-        assertEquals(500, attributes.getAttributeIntValue(BridgeConstants.NS_RESOURCES,
-                "layout_height", 500));
-        assertEquals(500, attributes.getAttributeIntValue(2, 500));
-
-        // Test project defined enum attribute
-        assertEquals(1, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(1, attributes.getAttributeIntValue(1, 500));
-        assertEquals(2, attributes.getAttributeIntValue("http://custom",
-                "my_custom_attr", 500));
-        assertEquals(2, attributes.getAttributeIntValue(1, 500));
-        // Test an invalid enum
-        boolean exception = false;
-        try {
-            attributes.getAttributeIntValue("http://custom", "my_custom_attr", 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-        exception = false;
-        try {
-            attributes.getAttributeIntValue(1, 500);
-        } catch(NumberFormatException e) {
-            exception = true;
-        }
-        assertTrue(exception);
-
-        // Test non existing project attribute
-        assertEquals(500, attributes.getAttributeIntValue("http://custom",
-                "my_other_attr", 500));
-    }
-
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
deleted file mode 100644
index 63b9b43..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/BridgeRenderSessionTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class BridgeRenderSessionTest {
-    @Test
-    public void testNullSession() {
-        BridgeRenderSession renderSession = new BridgeRenderSession(null, Status.ERROR_UNKNOWN
-                .createResult("Test result"));
-
-        assertNotNull(renderSession.getImage());
-        assertNotNull(renderSession.getRootViews());
-        assertNotNull(renderSession.getSystemRootViews());
-        assertNotNull(renderSession.getDefaultProperties());
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
deleted file mode 100644
index d8937f4..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.create.CreateInfo;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * Tests that native delegate classes implement all the required methods.
- *
- * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that
- * have their native methods reimplemented through a delegate.
- *
- * Since the reimplemented methods are not native anymore, we look for the annotation
- * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same
- * as the modified class with _Delegate added as a suffix).
- * If the original native method is not static, then we make sure the delegate method also
- * include the original class as first parameter (to access "this").
- *
- */
-public class TestDelegates extends TestCase {
-
-    private List<String> mErrors = new ArrayList<String>();
-
-    public void testNativeDelegates() {
-
-        final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES;
-        mErrors.clear();
-        for (String clazz : classes) {
-            loadAndCompareClasses(clazz, clazz + "_Delegate");
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    public void testMethodDelegates() {
-        final String[] methods = CreateInfo.DELEGATE_METHODS;
-        mErrors.clear();
-        for (String methodName : methods) {
-            // extract the class name
-            String className = methodName.substring(0, methodName.indexOf('#'));
-            String targetClassName = className.replace('$', '_') + "_Delegate";
-
-            loadAndCompareClasses(className, targetClassName);
-        }
-        assertTrue(getErrors(), mErrors.isEmpty());
-    }
-
-    private void loadAndCompareClasses(String originalClassName, String delegateClassName) {
-        // load the classes
-        try {
-            ClassLoader classLoader = TestDelegates.class.getClassLoader();
-            Class<?> originalClass = classLoader.loadClass(originalClassName);
-            Class<?> delegateClass = classLoader.loadClass(delegateClassName);
-
-            compare(originalClass, delegateClass);
-        } catch (ClassNotFoundException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        } catch (SecurityException e) {
-            mErrors.add("Failed to load class: " + e.getMessage());
-        }
-    }
-
-    private void compare(Class<?> originalClass, Class<?> delegateClass) throws SecurityException {
-        List<Method> checkedDelegateMethods = new ArrayList<Method>();
-
-        // loop on the methods of the original class, and for the ones that are annotated
-        // with @LayoutlibDelegate, look for a matching method in the delegate class.
-        // The annotation is automatically added by layoutlib_create when it replace a method
-        // by a call to a delegate
-        Method[] originalMethods = originalClass.getDeclaredMethods();
-        for (Method originalMethod : originalMethods) {
-            // look for methods that are delegated: they have the LayoutlibDelegate annotation
-            if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            // get the signature.
-            Class<?>[] parameters = originalMethod.getParameterTypes();
-
-            // if the method is not static, then the class is added as the first parameter
-            // (for "this")
-            if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) {
-
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass;
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            // if the original class is an inner class that's not static, then
-            // we add this on the enclosing class at the beginning
-            if (originalClass.getEnclosingClass() != null &&
-                    (originalClass.getModifiers() & Modifier.STATIC) == 0) {
-                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
-                newParameters[0] = originalClass.getEnclosingClass();
-                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
-                parameters = newParameters;
-            }
-
-            try {
-                // try to load the method with the given parameter types.
-                Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
-                        parameters);
-
-                // check the return type of the methods match.
-                if (delegateMethod.getReturnType() != originalMethod.getReturnType()) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s.%2$s does not match the " +
-                                    "corresponding framework method which returns %3$s",
-                            delegateClass.getName(),
-                            getMethodName(delegateMethod),
-                            originalMethod.getReturnType().getName()));
-                }
-
-                // check that the method has the annotation
-                if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                    mErrors.add(
-                            String.format("Delegate method %1$s for class %2$s does not have the " +
-                                            "@LayoutlibDelegate annotation",
-                                    delegateMethod.getName(),
-                                    originalClass.getName()));
-                }
-
-                // check that the method is static
-                if ((delegateMethod.getModifiers() & Modifier.STATIC) != Modifier.STATIC) {
-                    mErrors.add(
-                            String.format(
-                                    "Delegate method %1$s for class %2$s is not static",
-                                    delegateMethod.getName(),
-                                    originalClass.getName())
-                    );
-                }
-
-                // add the method as checked.
-                checkedDelegateMethods.add(delegateMethod);
-            } catch (NoSuchMethodException e) {
-                String name = getMethodName(originalMethod, parameters);
-                mErrors.add(String.format("Missing %1$s.%2$s", delegateClass.getName(), name));
-            }
-        }
-
-        // look for dead (delegate) code.
-        // This looks for all methods in the delegate class, and if they have the
-        // @LayoutlibDelegate annotation, make sure they have been previously found as a
-        // match for a method in the original class.
-        // If not, this means the method is a delegate for a method that either doesn't exist
-        // anymore or is not delegated anymore.
-        Method[] delegateMethods = delegateClass.getDeclaredMethods();
-        for (Method delegateMethod : delegateMethods) {
-            // look for methods that are delegates: they have the LayoutlibDelegate annotation
-            if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
-                continue;
-            }
-
-            if (!checkedDelegateMethods.contains(delegateMethod)) {
-                mErrors.add(String.format(
-                        "Delegate method %1$s.%2$s is not used anymore and must be removed",
-                        delegateClass.getName(),
-                        getMethodName(delegateMethod)));
-            }
-        }
-
-    }
-
-    private String getMethodName(Method method) {
-        return getMethodName(method, method.getParameterTypes());
-    }
-
-    private String getMethodName(Method method, Class<?>[] parameters) {
-        // compute a full class name that's long but not too long.
-        StringBuilder sb = new StringBuilder(method.getName() + "(");
-        for (int j = 0; j < parameters.length; j++) {
-            Class<?> theClass = parameters[j];
-            int dimensions = 0;
-            while (theClass.isArray()) {
-                dimensions++;
-                theClass = theClass.getComponentType();
-            }
-            sb.append(theClass.getName());
-            for (int i = 0; i < dimensions; i++) {
-                sb.append("[]");
-            }
-            if (j < (parameters.length - 1)) {
-                sb.append(",");
-            }
-        }
-        sb.append(")");
-
-        return sb.toString();
-    }
-
-    private String getErrors() {
-        StringBuilder s = new StringBuilder();
-        for (String error : mErrors) {
-            s.append(error).append('\n');
-        }
-        return s.toString();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
deleted file mode 100644
index 77c997b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.android;
-
-import com.android.layoutlib.bridge.impl.ParserFactory;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.w3c.dom.Node;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-
-import static org.junit.Assert.assertEquals;
-
-public class BridgeXmlBlockParserTest {
-
-    @BeforeClass
-    public static void setUp() {
-        ParserFactory.setParserFactory(new ParserFactoryImpl());
-    }
-
-    @Test
-    public void testXmlBlockParser() throws Exception {
-
-        XmlPullParser parser = ParserFactory.create(
-                getClass().getResourceAsStream("/com/android/layoutlib/testdata/layout1.xml"),
-                        "layout1.xml");
-
-        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
-
-        assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("LinearLayout", parser.getName());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("Button", parser.getName());
-        assertEquals(XmlPullParser.TEXT, parser.next());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("View", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.START_TAG, parser.next());
-        assertEquals("TextView", parser.getName());
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-
-        assertEquals(XmlPullParser.TEXT, parser.next());
-
-        assertEquals(XmlPullParser.END_TAG, parser.next());
-        assertEquals(XmlPullParser.END_DOCUMENT, parser.next());
-    }
-
-    //------------
-
-    /**
-     * Quick 'n' dirty debug helper that dumps an XML structure to stdout.
-     */
-    @SuppressWarnings("unused")
-    private void dump(Node node, String prefix) {
-        Node n;
-
-        String[] types = {
-                "unknown",
-                "ELEMENT_NODE",
-                "ATTRIBUTE_NODE",
-                "TEXT_NODE",
-                "CDATA_SECTION_NODE",
-                "ENTITY_REFERENCE_NODE",
-                "ENTITY_NODE",
-                "PROCESSING_INSTRUCTION_NODE",
-                "COMMENT_NODE",
-                "DOCUMENT_NODE",
-                "DOCUMENT_TYPE_NODE",
-                "DOCUMENT_FRAGMENT_NODE",
-                "NOTATION_NODE"
-        };
-
-        String s = String.format("%s<%s> %s %s",
-                prefix,
-                types[node.getNodeType()],
-                node.getNodeName(),
-                node.getNodeValue() == null ? "" : node.getNodeValue().trim());
-
-        System.out.println(s);
-
-        n = node.getFirstChild();
-        if (n != null) {
-            dump(n, prefix + "- ");
-        }
-
-        n = node.getNextSibling();
-        if (n != null) {
-            dump(n, prefix);
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        ParserFactory.setParserFactory(null);
-    }
-
-    private static class ParserFactoryImpl
-            extends com.android.ide.common.rendering.api.ParserFactory {
-
-        @NonNull
-        @Override
-        public XmlPullParser createParser(String displayName) throws XmlPullParserException {
-            return new KXmlParser();
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
deleted file mode 100644
index 2c33862..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/impl/LayoutParserWrapperTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.impl;
-
-import org.junit.Test;
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.StringReader;
-
-import static com.android.SdkConstants.NS_RESOURCES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
-
-public class LayoutParserWrapperTest {
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")  // some for loops need to be empty statements.
-    public void testDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that data-binding part is stripped.
-        assertEquals("Bound attribute android:text incorrect", "World",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    @Test
-    @SuppressWarnings("StatementWithEmptyBody")
-    public void testNonDataBindingLayout() throws Exception {
-        LayoutParserWrapper parser = getParserFromString(sNonDataBindingLayout);
-        parser.peekTillLayoutStart();
-        assertEquals("Expected START_TAG", START_TAG, parser.next());
-        assertEquals("RelativeLayout", parser.getName());
-        for (int next = parser.next(); next != START_TAG && next != END_DOCUMENT;
-             next = parser.next());
-        assertEquals("Expected START_TAG", START_TAG, parser.getEventType());
-        assertEquals("TextView", parser.getName());
-        assertEquals("layout_width incorrect for first text view.", "wrap_content",
-                parser.getAttributeValue(NS_RESOURCES, "layout_width"));
-        // Ensure that value isn't modified.
-        assertEquals("Bound attribute android:text incorrect", "@{user.firstName,default=World}",
-                parser.getAttributeValue(NS_RESOURCES, "text"));
-        assertEquals("resource attribute 'id' for first text view incorrect.", "@+id/first",
-                parser.getAttributeValue(NS_RESOURCES, "id"));
-        for (int next = parser.next();
-             (next != END_TAG || !"RelativeLayout".equals(parser.getName())) && next != END_DOCUMENT;
-             next = parser.next());
-        assertNotSame("Unexpected end of document", END_DOCUMENT, parser.getEventType());
-        assertEquals("Document didn't end when expected.", END_DOCUMENT, parser.next());
-    }
-
-    private static LayoutParserWrapper getParserFromString(String layoutContent) throws
-            XmlPullParserException {
-        XmlPullParser parser = new KXmlParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(new StringReader(layoutContent));
-        return new LayoutParserWrapper(parser);
-    }
-
-    private static final String sDataBindingLayout =
-            //language=XML
-            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-                    "<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "        xmlns:tools=\"http://schemas.android.com/tools\"\n" +
-                    "        tools:context=\".MainActivity\"\n" +
-                    "        tools:showIn=\"@layout/activity_main\">\n" +
-                    "\n" +
-                    "    <data>\n" +
-                    "\n" +
-                    "        <variable\n" +
-                    "            name=\"user\"\n" +
-                    "            type=\"com.example.User\" />\n" +
-                    "        <variable\n" +
-                    "            name=\"activity\"\n" +
-                    "            type=\"com.example.MainActivity\" />\n" +
-                    "    </data>\n" +
-                    "\n" +
-                    "    <RelativeLayout\n" +
-                    "        android:layout_width=\"match_parent\"\n" +
-                    "        android:layout_height=\"match_parent\"\n" +
-                    "        android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "        android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "        android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    "    >\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/first\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_alignParentStart=\"true\"\n" +
-                    "            android:layout_alignParentLeft=\"true\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "        <TextView\n" +
-                    "            android:id=\"@+id/last\"\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_toEndOf=\"@id/first\"\n" +
-                    "            android:layout_toRightOf=\"@id/first\"\n" +
-                    "            android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "        <Button\n" +
-                    "            android:layout_width=\"wrap_content\"\n" +
-                    "            android:layout_height=\"wrap_content\"\n" +
-                    "            android:layout_below=\"@id/last\"\n" +
-                    "            android:text=\"Submit\"\n" +
-                    "            android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "    </RelativeLayout>\n" +
-                    "</layout>";
-
-    private static final String sNonDataBindingLayout =
-            //language=XML
-            "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                    "    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n" +
-                    "    android:layout_width=\"match_parent\"\n" +
-                    "    android:layout_height=\"match_parent\"\n" +
-                    "    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n" +
-                    "    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                    "    android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                    "    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n" +
-                    ">\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/first\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_alignParentStart=\"true\"\n" +
-                    "        android:layout_alignParentLeft=\"true\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:text=\"@{user.firstName,default=World}\" />\n" +
-                    "\n" +
-                    "    <TextView\n" +
-                    "        android:id=\"@+id/last\"\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_toEndOf=\"@id/first\"\n" +
-                    "        android:layout_toRightOf=\"@id/first\"\n" +
-                    "        android:text=\"@{user.lastName,default=Hello}\" />\n" +
-                    "\n" +
-                    "    <Button\n" +
-                    "        android:layout_width=\"wrap_content\"\n" +
-                    "        android:layout_height=\"wrap_content\"\n" +
-                    "        android:layout_below=\"@id/last\"\n" +
-                    "        android:text=\"Submit\"\n" +
-                    "        android:onClick=\"@{activity.onClick}\"/>\n" +
-                    "</RelativeLayout>";
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
deleted file mode 100644
index eb264d65..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.layoutlib.bridge.BridgeRenderSessionTest;
-import com.android.layoutlib.bridge.TestDelegates;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest;
-import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-import android.graphics.Matrix_DelegateTest;
-import android.util.BridgeXmlPullAttributesTest;
-
-/**
- * Suite used by the layoutlib build system
- */
-@RunWith(Suite.class)
-@SuiteClasses({
-        RenderTests.class, LayoutParserWrapperTest.class,
-        BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
-        Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class,
-        BridgeRenderSessionTest.class
-})
-public class Main {
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
deleted file mode 100644
index 230e116..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.util.perf.PerformanceRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.annotation.NonNull;
-
-import java.io.FileNotFoundException;
-
-/**
- * Set of render tests
- */
-@RunWith(PerformanceRunner.class)
-public class PerformanceTests extends RenderTestBase {
-
-    @Before
-    public void setUp() {
-        ignoreAllLogging();
-    }
-
-
-    private void render(@NonNull String layoutFileName)
-            throws ClassNotFoundException, FileNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, ConfigGenerator.NEXUS_5);
-        render(params, 250);
-    }
-
-    @Test
-    public void testActivity() throws ClassNotFoundException, FileNotFoundException {
-        render("activity.xml");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException, FileNotFoundException {
-        render("allwidgets.xml");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
deleted file mode 100644
index 087478f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-class RenderResult {
-    private final List<ViewInfo> mRootViews;
-    private final List<ViewInfo> mSystemViews;
-    private final Result mRenderResult;
-    private BufferedImage mImage;
-
-    private RenderResult(@Nullable Result result, @Nullable List<ViewInfo> systemViewInfoList,
-            @Nullable List<ViewInfo> rootViewInfoList, @Nullable BufferedImage image) {
-        mSystemViews = systemViewInfoList == null ? Collections.emptyList() : systemViewInfoList;
-        mRootViews = rootViewInfoList == null ? Collections.emptyList() : rootViewInfoList;
-        mRenderResult = result;
-        mImage = image;
-    }
-
-    @NonNull
-    static RenderResult getFromSession(@NonNull RenderSession session) {
-        return new RenderResult(session.getResult(),
-                new ArrayList<>(session.getSystemRootViews()),
-                new ArrayList<>(session.getRootViews()),
-                session.getImage());
-    }
-
-    @Nullable
-    Result getResult() {
-        return mRenderResult;
-    }
-
-    @NonNull
-    public List<ViewInfo> getRootViews() {
-        return mRootViews;
-    }
-
-    @NonNull
-    public List<ViewInfo> getSystemViews() {
-        return mSystemViews;
-    }
-
-    @Nullable
-    public BufferedImage getImage() {
-        return mImage;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
deleted file mode 100644
index 62a803c..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.resources.FrameworkResources;
-import com.android.ide.common.resources.ResourceItem;
-import com.android.ide.common.resources.ResourceRepository;
-import com.android.ide.common.resources.ResourceResolver;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.io.FolderWrapper;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.layoutlib.bridge.intensive.util.ImageUtils;
-import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
-import com.android.layoutlib.bridge.intensive.util.TestAssetRepository;
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.utils.ILogger;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import com.google.android.collect.Lists;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-/**
- * Base class for render tests. The render tests load all the framework resources and a project
- * checked in this test's resources. The main dependencies
- * are:
- * 1. Fonts directory.
- * 2. Framework Resources.
- * 3. App resources.
- * 4. build.prop file
- * <p>
- * These are configured by two variables set in the system properties.
- * <p>
- * 1. platform.dir: This is the directory for the current platform in the built SDK
- * (.../sdk/platforms/android-<version>).
- * <p>
- * The fonts are platform.dir/data/fonts.
- * The Framework resources are platform.dir/data/res.
- * build.prop is at platform.dir/build.prop.
- * <p>
- * 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
- * falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
- * <p>
- * The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
- */
-public class RenderTestBase {
-
-    private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
-    private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
-
-    private static final String PLATFORM_DIR;
-    private static final String TEST_RES_DIR;
-    /** Location of the app to test inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_DIR = "testApp/MyApplication";
-    /** Location of the app's res dir inside {@link #TEST_RES_DIR} */
-    private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
-    private static final String APP_CLASSES_LOCATION =
-            APP_TEST_DIR + "/build/intermediates/classes/debug/";
-    protected static Bridge sBridge;
-    /** List of log messages generated by a render call. It can be used to find specific errors */
-    protected static ArrayList<String> sRenderMessages = Lists.newArrayList();
-    private static LayoutLog sLayoutLibLog;
-    private static FrameworkResources sFrameworkRepo;
-    private static ResourceRepository sProjectResources;
-    private static ILogger sLogger;
-
-    static {
-        // Test that System Properties are properly set.
-        PLATFORM_DIR = getPlatformDir();
-        if (PLATFORM_DIR == null) {
-            fail(String.format("System Property %1$s not properly set. The value is %2$s",
-                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
-        }
-
-        TEST_RES_DIR = getTestResDir();
-        if (TEST_RES_DIR == null) {
-            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
-                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
-        }
-    }
-
-    @Rule
-    public TestWatcher sRenderMessageWatcher = new TestWatcher() {
-        @Override
-        protected void succeeded(Description description) {
-            // We only check error messages if the rest of the test case was successful.
-            if (!sRenderMessages.isEmpty()) {
-                fail(description.getMethodName() + " render error message: " +
-                        sRenderMessages.get(0));
-            }
-        }
-    };
-    // Default class loader with access to the app classes
-    protected ClassLoader mDefaultClassLoader =
-            new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader());
-
-    private static String getPlatformDir() {
-        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
-        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
-            return platformDir;
-        }
-        // System Property not set. Try to find the directory in the build directory.
-        String androidHostOut = System.getenv("ANDROID_HOST_OUT");
-        if (androidHostOut != null) {
-            platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        String workingDirString = System.getProperty("user.dir");
-        File workingDir = new File(workingDirString);
-        // Test if workingDir is android checkout root.
-        platformDir = getPlatformDirFromRoot(workingDir);
-        if (platformDir != null) {
-            return platformDir;
-        }
-
-        // Test if workingDir is platform/frameworks/base/tools/layoutlib/bridge.
-        File currentDir = workingDir;
-        if (currentDir.getName().equalsIgnoreCase("bridge")) {
-            currentDir = currentDir.getParentFile();
-        }
-        // Test if currentDir is  platform/frameworks/base/tools/layoutlib. That is, root should be
-        // workingDir/../../../../  (4 levels up)
-        for (int i = 0; i < 4; i++) {
-            if (currentDir != null) {
-                currentDir = currentDir.getParentFile();
-            }
-        }
-        return currentDir == null ? null : getPlatformDirFromRoot(currentDir);
-    }
-
-    private static String getPlatformDirFromRoot(File root) {
-        if (!root.isDirectory()) {
-            return null;
-        }
-        File out = new File(root, "out");
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File host = new File(out, "host");
-        if (!host.isDirectory()) {
-            return null;
-        }
-        File[] hosts = host.listFiles(path -> path.isDirectory() &&
-                (path.getName().startsWith("linux-") || path.getName().startsWith("darwin-")));
-        assert hosts != null;
-        for (File hostOut : hosts) {
-            String platformDir = getPlatformDirFromHostOut(hostOut);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOut(File out) {
-        if (!out.isDirectory()) {
-            return null;
-        }
-        File sdkDir = new File(out, "sdk");
-        if (!sdkDir.isDirectory()) {
-            return null;
-        }
-        File[] sdkDirs = sdkDir.listFiles(path -> {
-            // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
-            return path.isDirectory() && path.getName().startsWith("sdk");
-        });
-        assert sdkDirs != null;
-        for (File dir : sdkDirs) {
-            String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
-            if (platformDir != null) {
-                return platformDir;
-            }
-        }
-        return null;
-    }
-
-    private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
-        File[] possibleSdks = sdkDir.listFiles(
-                path -> path.isDirectory() && path.getName().contains("android-sdk"));
-        assert possibleSdks != null;
-        for (File possibleSdk : possibleSdks) {
-            File platformsDir = new File(possibleSdk, "platforms");
-            File[] platforms = platformsDir.listFiles(
-                    path -> path.isDirectory() && path.getName().startsWith("android-"));
-            if (platforms == null || platforms.length == 0) {
-                continue;
-            }
-            Arrays.sort(platforms, (o1, o2) -> {
-                final int MAX_VALUE = 1000;
-                String suffix1 = o1.getName().substring("android-".length());
-                String suffix2 = o2.getName().substring("android-".length());
-                int suff1, suff2;
-                try {
-                    suff1 = Integer.parseInt(suffix1);
-                } catch (NumberFormatException e) {
-                    suff1 = MAX_VALUE;
-                }
-                try {
-                    suff2 = Integer.parseInt(suffix2);
-                } catch (NumberFormatException e) {
-                    suff2 = MAX_VALUE;
-                }
-                if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
-                    return suff2 - suff1;
-                }
-                return suffix2.compareTo(suffix1);
-            });
-            return platforms[0].getAbsolutePath();
-        }
-        return null;
-    }
-
-    private static String getTestResDir() {
-        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
-        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
-            return resourceDir;
-        }
-        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
-        try {
-            URL location = RenderTestBase.class.getProtectionDomain().getCodeSource().getLocation();
-            return new File(location.getPath()).exists() ? location.getPath() : null;
-        } catch (NullPointerException e) {
-            // Prevent a lot of null checks by just catching the exception.
-            return null;
-        }
-    }
-
-    /**
-     * Initialize the bridge and the resource maps.
-     */
-    @BeforeClass
-    public static void beforeClass() {
-        File data_dir = new File(PLATFORM_DIR, "data");
-        File res = new File(data_dir, "res");
-        sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
-        sFrameworkRepo.loadResources();
-        sFrameworkRepo.loadPublicResources(getLogger());
-
-        sProjectResources =
-                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
-                        false) {
-                    @NonNull
-                    @Override
-                    protected ResourceItem createResourceItem(@NonNull String name) {
-                        return new ResourceItem(name);
-                    }
-                };
-        sProjectResources.loadResources();
-
-        File fontLocation = new File(data_dir, "fonts");
-        File buildProp = new File(PLATFORM_DIR, "build.prop");
-        File attrs = new File(res, "values" + File.separator + "attrs.xml");
-        sBridge = new Bridge();
-        sBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
-                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
-        Bridge.getLock().lock();
-        try {
-            Bridge.setLog(getLayoutLog());
-        } finally {
-            Bridge.getLock().unlock();
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() {
-        sLayoutLibLog = null;
-        sFrameworkRepo = null;
-        sProjectResources = null;
-        sLogger = null;
-        sBridge = null;
-
-        TestUtils.gc();
-
-        System.out.println("Objects still linked from the DelegateManager:");
-        DelegateManager.dump(System.out);
-    }
-
-    @NonNull
-    protected static RenderResult render(SessionParams params, long frameTimeNanos) {
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
-        RenderSession session = sBridge.createSession(params);
-
-        try {
-            if (frameTimeNanos != -1) {
-                session.setElapsedFrameTimeNanos(frameTimeNanos);
-            }
-
-            if (!session.getResult().isSuccess()) {
-                getLogger().error(session.getResult().getException(),
-                        session.getResult().getErrorMessage());
-            }
-            else {
-                // Render the session with a timeout of 50s.
-                Result renderResult = session.render(50000);
-                if (!renderResult.isSuccess()) {
-                    getLogger().error(session.getResult().getException(),
-                            session.getResult().getErrorMessage());
-                }
-            }
-
-            return RenderResult.getFromSession(session);
-        } finally {
-            session.dispose();
-        }
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     * <p>
-     * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
-     * how far in the future is.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName,
-            long frameTimeNanos) throws ClassNotFoundException {
-        RenderResult result = RenderTestBase.render(params, frameTimeNanos);
-        try {
-            String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
-            assertNotNull(result.getImage());
-            ImageUtils.requireSimilar(goldenImagePath, result.getImage());
-        } catch (IOException e) {
-            getLogger().error(e, e.getMessage());
-        }
-
-        return result;
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout doesn't throw any
-     * exceptions and matches the provided image.
-     */
-    @Nullable
-    protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName)
-            throws ClassNotFoundException {
-        return RenderTestBase.renderAndVerify(params, goldenFileName, -1);
-    }
-
-    private static LayoutLog getLayoutLog() {
-        if (sLayoutLibLog == null) {
-            sLayoutLibLog = new LayoutLog() {
-                @Override
-                public void warning(String tag, String message, Object data) {
-                    System.out.println("Warning " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void fidelityWarning(@Nullable String tag, String message,
-                        Throwable throwable, Object data) {
-
-                    System.out.println("FidelityWarning " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message == null ? "" : message);
-                }
-
-                @Override
-                public void error(String tag, String message, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    failWithMsg(message);
-                }
-
-                @Override
-                public void error(String tag, String message, Throwable throwable, Object data) {
-                    System.out.println("Error " + tag + ": " + message);
-                    if (throwable != null) {
-                        throwable.printStackTrace();
-                    }
-                    failWithMsg(message);
-                }
-            };
-        }
-        return sLayoutLibLog;
-    }
-
-    protected static void ignoreAllLogging() {
-        sLayoutLibLog = new LayoutLog();
-        sLogger = new ILogger() {
-            @Override
-            public void error(Throwable t, String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void warning(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void info(String msgFormat, Object... args) {
-            }
-
-            @Override
-            public void verbose(String msgFormat, Object... args) {
-            }
-        };
-    }
-
-    protected static ILogger getLogger() {
-        if (sLogger == null) {
-            sLogger = new ILogger() {
-                @Override
-                public void error(Throwable t, @Nullable String msgFormat, Object... args) {
-                    if (t != null) {
-                        t.printStackTrace();
-                    }
-                    failWithMsg(msgFormat == null ? "" : msgFormat, args);
-                }
-
-                @Override
-                public void warning(@NonNull String msgFormat, Object... args) {
-                    failWithMsg(msgFormat, args);
-                }
-
-                @Override
-                public void info(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-
-                @Override
-                public void verbose(@NonNull String msgFormat, Object... args) {
-                    // pass.
-                }
-            };
-        }
-        return sLogger;
-    }
-
-    private static void failWithMsg(@NonNull String msgFormat, Object... args) {
-        sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args));
-    }
-
-    @Before
-    public void beforeTestCase() {
-        sRenderMessages.clear();
-    }
-
-    @NonNull
-    protected LayoutPullParser createParserFromPath(String layoutPath)
-            throws FileNotFoundException {
-        return LayoutPullParser.createFromPath(APP_TEST_RES + "/layout/" + layoutPath);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on nexus 5
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName)
-            throws ClassNotFoundException, FileNotFoundException {
-        return renderAndVerify(layoutFileName, goldenFileName, ConfigGenerator.NEXUS_5);
-    }
-
-    /**
-     * Create a new rendering session and test that rendering the given layout on given device
-     * doesn't throw any exceptions and matches the provided image.
-     */
-    @Nullable
-    protected RenderResult renderAndVerify(String layoutFileName, String goldenFileName,
-            ConfigGenerator deviceConfig) throws ClassNotFoundException, FileNotFoundException {
-        SessionParams params = createSessionParams(layoutFileName, deviceConfig);
-        return renderAndVerify(params, goldenFileName);
-    }
-
-    protected SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
-            throws ClassNotFoundException, FileNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createParserFromPath(layoutFileName);
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        // TODO: Set up action bar handler properly to test menu rendering.
-        // Create session params.
-        return getSessionParams(parser, deviceConfig, layoutLibCallback, "AppTheme", true,
-                RenderingMode.NORMAL, 22);
-    }
-
-    /**
-     * Uses Theme.Material and Target sdk version as 22.
-     */
-    protected SessionParams getSessionParams(LayoutPullParser layoutParser,
-            ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback,
-            String themeName, boolean isProjectTheme, RenderingMode renderingMode,
-            @SuppressWarnings("SameParameterValue") int targetSdk) {
-        FolderConfiguration config = configGenerator.getFolderConfig();
-        ResourceResolver resourceResolver =
-                ResourceResolver.create(sProjectResources.getConfiguredResources(config),
-                        sFrameworkRepo.getConfiguredResources(config), themeName, isProjectTheme);
-
-        SessionParams sessionParams =
-                new SessionParams(layoutParser, renderingMode, null /*used for caching*/,
-                        configGenerator.getHardwareConfig(), resourceResolver, layoutLibCallback, 0,
-                        targetSdk, getLayoutLog());
-        sessionParams.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true);
-        sessionParams.setAssetRepository(new TestAssetRepository());
-        return sessionParams;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
deleted file mode 100644
index 833652a..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.resources.Density;
-import com.android.resources.Navigation;
-import com.android.resources.ResourceType;
-
-import org.junit.Test;
-
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-
-import java.io.FileNotFoundException;
-import java.lang.reflect.Field;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Set of render tests
- */
-public class RenderTests extends RenderTestBase {
-
-    @Test
-    public void testActivity() throws ClassNotFoundException, FileNotFoundException {
-        renderAndVerify("activity.xml", "activity.png");
-    }
-
-    @Test
-    public void testActivityOnOldTheme() throws ClassNotFoundException, FileNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = LayoutPullParser.createFromString(
-                "<RelativeLayout xmlns:android=\"http://schemas" +
-                ".android.com/apk/res/android\"\n" +
-                "                android:layout_width=\"match_parent\"\n" +
-                "                android:layout_height=\"match_parent\"\n" +
-                "                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                "                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                "                android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                "                android:paddingBottom=\"@dimen/activity_vertical_margin\">\n" +
-                "    <TextView\n" +
-                "        android:text=\"@string/hello_world\"\n" +
-                "        android:layout_width=\"wrap_content\"\n" +
-                "        android:layout_height=\"200dp\"\n" +
-                "        android:background=\"#FF0000\"\n" +
-                "        android:id=\"@+id/text1\"/>\n" +
-                "</RelativeLayout>");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.NoTitleBar", false,
-                RenderingMode.NORMAL, 22);
-
-        renderAndVerify(params, "simple_activity-old-theme.png");
-    }
-
-    @Test
-    public void testTranslucentBars() throws ClassNotFoundException, FileNotFoundException {
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        LayoutPullParser parser = createParserFromPath("four_corners.xml");
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent.png");
-
-        parser = createParserFromPath("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5_LAND,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.TranslucentDecor", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners_translucent_land.png");
-
-        parser = createParserFromPath("four_corners.xml");
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-        renderAndVerify(params, "four_corners.png");
-    }
-
-    @Test
-    public void testAllWidgets() throws ClassNotFoundException, FileNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets.png");
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testArrayCheck() throws ClassNotFoundException, FileNotFoundException {
-        renderAndVerify("array_check.xml", "array_check.png");
-    }
-
-    @Test
-    public void testAllWidgetsTablet() throws ClassNotFoundException, FileNotFoundException {
-        renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012);
-
-        // We expect fidelity warnings for Path.isConvex. Fail for anything else.
-        sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported."));
-    }
-
-    @Test
-    public void testActivityActionBar() throws ClassNotFoundException {
-        String simpleActivity =
-                "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                "                android:layout_width=\"match_parent\"\n" +
-                "                android:layout_height=\"match_parent\"\n" +
-                "                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
-                "                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
-                "                android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
-                "                android:paddingBottom=\"@dimen/activity_vertical_margin\">\n" +
-                "    <TextView\n" +
-                "        android:text=\"@string/hello_world\"\n" +
-                "        android:layout_width=\"wrap_content\"\n" +
-                "        android:layout_height=\"200dp\"\n" +
-                "        android:background=\"#FF0000\"\n" +
-                "        android:id=\"@+id/text1\"/>\n" +
-                "</RelativeLayout>";
-
-        LayoutPullParser parser = LayoutPullParser.createFromString(simpleActivity);
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity_noactionbar.png");
-
-        parser = LayoutPullParser.createFromString(simpleActivity);
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "simple_activity.png");
-
-        // This also tests that a theme with "NoActionBar" DOES HAVE an action bar when we are
-        // displaying menus.
-        parser = LayoutPullParser.createFromString(simpleActivity);
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG, "menu");
-        renderAndVerify(params, "simple_activity.png");
-    }
-
-    @Test
-    public void testOnApplyInsetsCall()
-            throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
-        // We get the widget via reflection to avoid IntelliJ complaining about the class being
-        // located in the wrong package. (From the Bridge tests point of view, it is)
-        Class insetsWidgetClass = Class.forName("com.android.layoutlib.test.myapplication.widgets" +
-                ".InsetsWidget");
-        Field field = insetsWidgetClass.getDeclaredField("sApplyInsetsCalled");
-        assertFalse((Boolean)field.get(null));
-
-        LayoutPullParser parser = LayoutPullParser.createFromString(
-                "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                "              android:padding=\"16dp\"\n" +
-                "              android:orientation=\"horizontal\"\n" +
-                "              android:layout_width=\"wrap_content\"\n" +
-                "              android:layout_height=\"wrap_content\">\n" + "\n" +
-                "    <com.android.layoutlib.test.myapplication.widgets.InsetsWidget\n" +
-                "        android:text=\"Hello world\"\n" +
-                "        android:layout_width=\"wrap_content\"\n" +
-                "        android:layout_height=\"wrap_content\"\n" +
-                "        android:id=\"@+id/text1\"/>\n" + "</LinearLayout>\n");
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar", false,
-                RenderingMode.NORMAL, 22);
-
-        render(params, -1);
-
-        assertTrue((Boolean)field.get(null));
-        field.set(null, false);
-    }
-
-    /** Test expand_layout.xml */
-    @Test
-    public void testExpand() throws ClassNotFoundException, FileNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createParserFromPath("expand_vert_layout.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        ConfigGenerator customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(300)
-                .setScreenHeight(20)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-
-        SessionParams params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "expand_vert_layout.png");
-
-        customConfigGenerator = new ConfigGenerator()
-                .setScreenWidth(20)
-                .setScreenHeight(300)
-                .setDensity(Density.XHIGH)
-                .setNavigation(Navigation.NONAV);
-        parser = createParserFromPath("expand_horz_layout.xml");
-        params = getSessionParams(parser, customConfigGenerator,
-                layoutLibCallback, "Theme.Material.Light.NoActionBar.Fullscreen", false,
-                RenderingMode.H_SCROLL, 22);
-
-        renderAndVerify(params, "expand_horz_layout.png");
-    }
-
-    /** Test indeterminate_progressbar.xml */
-    @Test
-    public void testVectorAnimation() throws ClassNotFoundException {
-        String layout = "\n" +
-                "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                "              android:padding=\"16dp\"\n" +
-                "              android:orientation=\"horizontal\"\n" +
-                "              android:layout_width=\"fill_parent\"\n" +
-                "              android:layout_height=\"fill_parent\">\n" + "\n" +
-                "    <ProgressBar\n" + "             android:layout_height=\"fill_parent\"\n" +
-                "             android:layout_width=\"fill_parent\" />\n" + "\n" +
-                "</LinearLayout>\n";
-
-        // Create the layout pull parser.
-        LayoutPullParser parser = LayoutPullParser.createFromString(layout);
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "animated_vector.png", TimeUnit.SECONDS.toNanos(2));
-
-        parser = LayoutPullParser.createFromString(layout);
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        renderAndVerify(params, "animated_vector_1.png", TimeUnit.SECONDS.toNanos(3));
-    }
-
-    /**
-     * Test a vector drawable that uses trimStart and trimEnd. It also tests all the primitives
-     * for vector drawables (lines, moves and cubic and quadratic curves).
-     */
-    @Test
-    public void testVectorDrawable() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = LayoutPullParser.createFromString(
-               "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                       "              android:padding=\"16dp\"\n" +
-                       "              android:orientation=\"horizontal\"\n" +
-                       "              android:layout_width=\"fill_parent\"\n" +
-                       "              android:layout_height=\"fill_parent\">\n" +
-                       "    <ImageView\n" +
-                       "             android:layout_height=\"fill_parent\"\n" +
-                       "             android:layout_width=\"fill_parent\"\n" +
-                       "             android:src=\"@drawable/multi_path\" />\n" + "\n" +
-                       "</LinearLayout>");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /**
-     * Regression test for http://b.android.com/91383 and http://b.android.com/203797
-     */
-    @Test
-    public void testVectorDrawable91383() throws ClassNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = LayoutPullParser.createFromString(
-                "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                        "              android:padding=\"16dp\"\n" +
-                        "              android:orientation=\"vertical\"\n" +
-                        "              android:layout_width=\"fill_parent\"\n" +
-                        "              android:layout_height=\"fill_parent\">\n" +
-                        "    <ImageView\n" +
-                        "        android:layout_height=\"wrap_content\"\n" +
-                        "        android:layout_width=\"wrap_content\"\n" +
-                        "        android:src=\"@drawable/android\"/>\n" +
-                        "    <ImageView\n" +
-                        "        android:layout_height=\"wrap_content\"\n" +
-                        "        android:layout_width=\"wrap_content\"\n" +
-                        "        android:src=\"@drawable/headset\"/>\n" +
-                        "</LinearLayout>");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "vector_drawable_91383.png", TimeUnit.SECONDS.toNanos(2));
-    }
-
-    /** Test activity.xml */
-    @Test
-    public void testScrollingAndMeasure() throws ClassNotFoundException, FileNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = createParserFromPath("scrolled.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        // Do an only-measure pass
-        RenderSession session = sBridge.createSession(params);
-        session.measure();
-        RenderResult result = RenderResult.getFromSession(session);
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-
-        ViewInfo rootLayout = result.getRootViews().get(0);
-        // Check the first box in the main LinearLayout
-        assertEquals(-90, rootLayout.getChildren().get(0).getTop());
-        assertEquals(-30, rootLayout.getChildren().get(0).getLeft());
-        assertEquals(90, rootLayout.getChildren().get(0).getBottom());
-        assertEquals(150, rootLayout.getChildren().get(0).getRight());
-
-        // Check the first box within the nested LinearLayout
-        assertEquals(-450, rootLayout.getChildren().get(5).getChildren().get(0).getTop());
-        assertEquals(90, rootLayout.getChildren().get(5).getChildren().get(0).getLeft());
-        assertEquals(-270, rootLayout.getChildren().get(5).getChildren().get(0).getBottom());
-        assertEquals(690, rootLayout.getChildren().get(5).getChildren().get(0).getRight());
-
-        // Do a full render pass
-        parser = createParserFromPath("scrolled.xml");
-
-        params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-        params.setForceNoDecor();
-        params.setExtendedViewInfoMode(true);
-
-        result = renderAndVerify(params, "scrolled.png");
-        assertNotNull(result);
-        assertNotNull(result.getResult());
-        assertTrue(result.getResult().isSuccess());
-    }
-
-    @Test
-    public void testGetResourceNameVariants() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-        // Test
-        assertEquals("android:style/ButtonBar",
-                resources.getResourceName(android.R.style.ButtonBar));
-        assertEquals("android", resources.getResourcePackageName(android.R.style.ButtonBar));
-        assertEquals("ButtonBar", resources.getResourceEntryName(android.R.style.ButtonBar));
-        assertEquals("style", resources.getResourceTypeName(android.R.style.ButtonBar));
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.STRING, "app_name");
-        assertEquals("com.android.layoutlib.test.myapplication:string/app_name",
-                resources.getResourceName(id));
-        assertEquals("com.android.layoutlib.test.myapplication",
-                resources.getResourcePackageName(id));
-        assertEquals("string", resources.getResourceTypeName(id));
-        assertEquals("app_name", resources.getResourceEntryName(id));
-    }
-
-    @Test
-    public void testStringEscaping() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        int id = resources.mLayoutlibCallback.getResourceId(ResourceType.ARRAY, "string_array");
-        String[] strings = resources.getStringArray(id);
-        assertArrayEquals(
-                new String[]{"mystring", "Hello world!", "candidates", "Unknown", "?EC"},
-                strings);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    @Test
-    public void testFonts() throws ClassNotFoundException, FileNotFoundException {
-        // TODO: styles seem to be broken in TextView
-        renderAndVerify("fonts_test.xml", "font_test.png");
-    }
-
-    @Test
-    public void testAdaptiveIcon() throws ClassNotFoundException, FileNotFoundException {
-        // Create the layout pull parser.
-        LayoutPullParser parser = LayoutPullParser.createFromString(
-                "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-                        "              android:padding=\"16dp\"\n" +
-                        "              android:orientation=\"horizontal\"\n" +
-                        "              android:layout_width=\"fill_parent\"\n" +
-                        "              android:layout_height=\"fill_parent\">\n" +
-                        "    <ImageView\n" +
-                        "             android:layout_height=\"wrap_content\"\n" +
-                        "             android:layout_width=\"wrap_content\"\n" +
-                        "             android:src=\"@drawable/adaptive\" />\n" +
-                        "</LinearLayout>\n");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5,
-                layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false,
-                RenderingMode.V_SCROLL, 22);
-
-        renderAndVerify(params, "adaptive_icon.png");
-    }
-
-    @Test
-    public void testColorTypedValue() throws Exception {
-        // Setup
-        // Create the layout pull parser for our resources (empty.xml can not be part of the test
-        // app as it won't compile).
-        LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
-        // Create LayoutLibCallback.
-        LayoutLibTestCallback layoutLibCallback =
-                new LayoutLibTestCallback(RenderTestBase.getLogger(), mDefaultClassLoader);
-        layoutLibCallback.initResources();
-        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_4,
-                layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22);
-        AssetManager assetManager = AssetManager.getSystem();
-        DisplayMetrics metrics = new DisplayMetrics();
-        Configuration configuration = RenderAction.getConfiguration(params);
-        //noinspection deprecation
-        Resources resources = new Resources(assetManager, metrics, configuration);
-        resources.mLayoutlibCallback = params.getLayoutlibCallback();
-        resources.mContext =
-                new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
-                        params.getAssets(), params.getLayoutlibCallback(), configuration,
-                        params.getTargetSdkVersion(), params.isRtlSupported());
-
-        TypedValue outValue = new TypedValue();
-        resources.mContext.resolveThemeAttribute(android.R.attr.colorPrimary, outValue, true);
-        assertEquals(TypedValue.TYPE_INT_COLOR_ARGB8, outValue.type);
-        assertNotEquals(0, outValue.data);
-        assertTrue(sRenderMessages.isEmpty());
-    }
-
-    @Test
-    public void testRectangleShadow() throws Exception {
-        renderAndVerify("shadows_test.xml", "shadows_test.png");
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
deleted file mode 100644
index 34fc726..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.resources.configuration.CountryCodeQualifier;
-import com.android.ide.common.resources.configuration.DensityQualifier;
-import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
-import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
-import com.android.ide.common.resources.configuration.LocaleQualifier;
-import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
-import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
-import com.android.ide.common.resources.configuration.NightModeQualifier;
-import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
-import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
-import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
-import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
-import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
-import com.android.ide.common.resources.configuration.TouchScreenQualifier;
-import com.android.ide.common.resources.configuration.UiModeQualifier;
-import com.android.ide.common.resources.configuration.VersionQualifier;
-import com.android.resources.Density;
-import com.android.resources.Keyboard;
-import com.android.resources.KeyboardState;
-import com.android.resources.Navigation;
-import com.android.resources.NightMode;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRatio;
-import com.android.resources.ScreenSize;
-import com.android.resources.TouchScreen;
-import com.android.resources.UiMode;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-
-import com.google.android.collect.Maps;
-
-/**
- * Provides {@link FolderConfiguration} and {@link HardwareConfig} for various devices. Also
- * provides utility methods to parse build.prop and attrs.xml to generate the appropriate maps.
- */
-@SuppressWarnings("UnusedDeclaration") // For the pre-configured nexus generators.
-public class ConfigGenerator {
-
-    public static final ConfigGenerator NEXUS_4 = new ConfigGenerator();
-
-    public static final ConfigGenerator NEXUS_5 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1080)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7 = new ConfigGenerator()
-                                                        .setScreenHeight(1920)
-                                                        .setScreenWidth(1200)
-                                                        .setXdpi(323)
-                                                        .setYdpi(323)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_10 = new ConfigGenerator()
-                                                        .setScreenHeight(1600)
-                                                        .setScreenWidth(2560)
-                                                        .setXdpi(300)
-                                                        .setYdpi(300)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.XLARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_5_LAND = new ConfigGenerator()
-                                                        .setScreenHeight(1080)
-                                                        .setScreenWidth(1920)
-                                                        .setXdpi(445)
-                                                        .setYdpi(445)
-                                                        .setOrientation(ScreenOrientation.LANDSCAPE)
-                                                        .setDensity(Density.XXHIGH)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.NORMAL)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    public static final ConfigGenerator NEXUS_7_2012 = new ConfigGenerator()
-                                                        .setScreenHeight(1280)
-                                                        .setScreenWidth(800)
-                                                        .setXdpi(195)
-                                                        .setYdpi(200)
-                                                        .setOrientation(ScreenOrientation.PORTRAIT)
-                                                        .setDensity(Density.TV)
-                                                        .setRatio(ScreenRatio.NOTLONG)
-                                                        .setSize(ScreenSize.LARGE)
-                                                        .setKeyboard(Keyboard.NOKEY)
-                                                        .setTouchScreen(TouchScreen.FINGER)
-                                                        .setKeyboardState(KeyboardState.SOFT)
-                                                        .setSoftButtons(true)
-                                                        .setNavigation(Navigation.NONAV);
-
-    private static final String TAG_ATTR = "attr";
-    private static final String TAG_ENUM = "enum";
-    private static final String TAG_FLAG = "flag";
-    private static final String ATTR_NAME = "name";
-    private static final String ATTR_VALUE = "value";
-
-    // Device Configuration. Defaults are for a Nexus 4 device.
-    private int mScreenHeight = 1280;
-    private int mScreenWidth = 768;
-    private int mXdpi = 320;
-    private int mYdpi = 320;
-    private ScreenOrientation mOrientation = ScreenOrientation.PORTRAIT;
-    private Density mDensity = Density.XHIGH;
-    private ScreenRatio mRatio = ScreenRatio.NOTLONG;
-    private ScreenSize mSize = ScreenSize.NORMAL;
-    private Keyboard mKeyboard = Keyboard.NOKEY;
-    private TouchScreen mTouchScreen = TouchScreen.FINGER;
-    private KeyboardState mKeyboardState = KeyboardState.SOFT;
-    private boolean mSoftButtons = true;
-    private Navigation mNavigation = Navigation.NONAV;
-
-    public FolderConfiguration getFolderConfig() {
-        FolderConfiguration config = new FolderConfiguration();
-        config.createDefault();
-        config.setDensityQualifier(new DensityQualifier(mDensity));
-        config.setNavigationMethodQualifier(new NavigationMethodQualifier(mNavigation));
-        if (mScreenWidth > mScreenHeight) {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenWidth,
-                    mScreenHeight));
-        } else {
-            config.setScreenDimensionQualifier(new ScreenDimensionQualifier(mScreenHeight,
-                    mScreenWidth));
-        }
-        config.setScreenRatioQualifier(new ScreenRatioQualifier(mRatio));
-        config.setScreenSizeQualifier(new ScreenSizeQualifier(mSize));
-        config.setTextInputMethodQualifier(new TextInputMethodQualifier(mKeyboard));
-        config.setTouchTypeQualifier(new TouchScreenQualifier(mTouchScreen));
-        config.setKeyboardStateQualifier(new KeyboardStateQualifier(mKeyboardState));
-        config.setScreenOrientationQualifier(new ScreenOrientationQualifier(mOrientation));
-
-        config.updateScreenWidthAndHeight();
-
-        // some default qualifiers.
-        config.setUiModeQualifier(new UiModeQualifier(UiMode.NORMAL));
-        config.setNightModeQualifier(new NightModeQualifier(NightMode.NOTNIGHT));
-        config.setCountryCodeQualifier(new CountryCodeQualifier());
-        config.setLayoutDirectionQualifier(new LayoutDirectionQualifier());
-        config.setNetworkCodeQualifier(new NetworkCodeQualifier());
-        config.setLocaleQualifier(new LocaleQualifier());
-        config.setVersionQualifier(new VersionQualifier());
-        return config;
-    }
-
-    public HardwareConfig getHardwareConfig() {
-        return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mSize,
-                mOrientation, null, mSoftButtons);
-    }
-
-    public static Map<String, String> loadProperties(File path) {
-        Properties p = new Properties();
-        Map<String, String> map = Maps.newHashMap();
-        try {
-            p.load(new FileInputStream(path));
-            for (String key : p.stringPropertyNames()) {
-                map.put(key, p.getProperty(key));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    public static Map<String, Map<String, Integer>> getEnumMap(File path) {
-        Map<String, Map<String, Integer>> map = Maps.newHashMap();
-        try {
-            XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
-            xmlPullParser.setInput(new FileInputStream(path), null);
-            int eventType = xmlPullParser.getEventType();
-            String attr = null;
-            while (eventType != XmlPullParser.END_DOCUMENT) {
-                if (eventType == XmlPullParser.START_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                    } else if (TAG_ENUM.equals(xmlPullParser.getName())
-                            || TAG_FLAG.equals(xmlPullParser.getName())) {
-                        String name = xmlPullParser.getAttributeValue(null, ATTR_NAME);
-                        String value = xmlPullParser.getAttributeValue(null, ATTR_VALUE);
-                        // Integer.decode cannot handle "ffffffff", see JDK issue 6624867
-                        int i = (int) (long) Long.decode(value);
-                        assert attr != null;
-                        Map<String, Integer> attributeMap = map.get(attr);
-                        if (attributeMap == null) {
-                            attributeMap = Maps.newHashMap();
-                            map.put(attr, attributeMap);
-                        }
-                        attributeMap.put(name, i);
-                    }
-                } else if (eventType == XmlPullParser.END_TAG) {
-                    if (TAG_ATTR.equals(xmlPullParser.getName())) {
-                        attr = null;
-                    }
-                }
-                eventType = xmlPullParser.next();
-            }
-        } catch (XmlPullParserException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return map;
-    }
-
-    // Methods to set the configuration values.
-
-    public ConfigGenerator setScreenHeight(int height) {
-        mScreenHeight = height;
-        return this;
-    }
-
-    public ConfigGenerator setScreenWidth(int width) {
-        mScreenWidth = width;
-        return this;
-    }
-
-    public ConfigGenerator setXdpi(int xdpi) {
-        mXdpi = xdpi;
-        return this;
-    }
-
-    public ConfigGenerator setYdpi(int ydpi) {
-        mYdpi = ydpi;
-        return this;
-    }
-
-    public ConfigGenerator setOrientation(ScreenOrientation orientation) {
-        mOrientation = orientation;
-        return this;
-    }
-
-    public ConfigGenerator setDensity(Density density) {
-        mDensity = density;
-        return this;
-    }
-
-    public ConfigGenerator setRatio(ScreenRatio ratio) {
-        mRatio = ratio;
-        return this;
-    }
-
-    public ConfigGenerator setSize(ScreenSize size) {
-        mSize = size;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboard(Keyboard keyboard) {
-        mKeyboard = keyboard;
-        return this;
-    }
-
-    public ConfigGenerator setTouchScreen(TouchScreen touchScreen) {
-        mTouchScreen = touchScreen;
-        return this;
-    }
-
-    public ConfigGenerator setKeyboardState(KeyboardState state) {
-        mKeyboardState = state;
-        return this;
-    }
-
-    public ConfigGenerator setSoftButtons(boolean softButtons) {
-        mSoftButtons = softButtons;
-        return this;
-    }
-
-    public ConfigGenerator setNavigation(Navigation navigation) {
-        mNavigation = navigation;
-        return this;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
deleted file mode 100644
index 75145d7..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.setup;
-
-import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ParserFactory;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.ide.common.resources.IntArrayWrapper;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
-import com.android.resources.ResourceType;
-import com.android.util.Pair;
-import com.android.utils.ILogger;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-
-import static org.junit.Assert.fail;
-
-@SuppressWarnings("deprecation") // For Pair
-public class LayoutLibTestCallback extends LayoutlibCallback {
-
-    private static final String PROJECT_CLASSES_LOCATION = "/testApp/MyApplication/build/intermediates/classes/debug/";
-    private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
-
-    private final Map<Integer, Pair<ResourceType, String>> mProjectResources = Maps.newHashMap();
-    private final Map<IntArrayWrapper, String> mStyleableValueToNameMap = Maps.newHashMap();
-    private final Map<ResourceType, Map<String, Integer>> mResources = Maps.newHashMap();
-    private final ILogger mLog;
-    private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
-    private final ClassLoader mModuleClassLoader;
-
-    public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
-        mLog = logger;
-        mModuleClassLoader = classLoader;
-    }
-
-    public void initResources() throws ClassNotFoundException {
-        Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
-        Class<?>[] nestedClasses = rClass.getDeclaredClasses();
-        for (Class<?> resClass : nestedClasses) {
-            final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
-
-            if (resType != null) {
-                final Map<String, Integer> resName2Id = Maps.newHashMap();
-                mResources.put(resType, resName2Id);
-
-                for (Field field : resClass.getDeclaredFields()) {
-                    final int modifiers = field.getModifiers();
-                    if (Modifier.isStatic(modifiers)) { // May not be final in library projects
-                        final Class<?> type = field.getType();
-                        try {
-                            if (type.isArray() && type.getComponentType() == int.class) {
-                                mStyleableValueToNameMap.put(
-                                        new IntArrayWrapper((int[]) field.get(null)),
-                                        field.getName());
-                            } else if (type == int.class) {
-                                final Integer value = (Integer) field.get(null);
-                                mProjectResources.put(value, Pair.of(resType, field.getName()));
-                                resName2Id.put(field.getName(), value);
-                            } else {
-                                mLog.error(null, "Unknown field type in R class: %1$s", type);
-                            }
-                        } catch (IllegalAccessException ignored) {
-                            mLog.error(ignored, "Malformed R class: %1$s", PACKAGE_NAME + ".R");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
-            throws Exception {
-        Class<?> viewClass = mModuleClassLoader.loadClass(name);
-        Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
-        viewConstructor.setAccessible(true);
-        return viewConstructor.newInstance(constructorArgs);
-    }
-
-    @Override
-    public String getNamespace() {
-        return String.format(SdkConstants.NS_CUSTOM_RESOURCES_S,
-                PACKAGE_NAME);
-    }
-
-    @Override
-    public Pair<ResourceType, String> resolveResourceId(int id) {
-        return mProjectResources.get(id);
-    }
-
-    @Override
-    public String resolveResourceId(int[] id) {
-        return mStyleableValueToNameMap.get(new IntArrayWrapper(id));
-    }
-
-    @Override
-    public Integer getResourceId(ResourceType type, String name) {
-        Map<String, Integer> resName2Id = mResources.get(type);
-        if (resName2Id == null) {
-            return null;
-        }
-        return resName2Id.get(name);
-    }
-
-    @Override
-    public ILayoutPullParser getParser(String layoutName) {
-        fail("This method shouldn't be called by this version of LayoutLib.");
-        return null;
-    }
-
-    @Override
-    public ILayoutPullParser getParser(ResourceValue layoutResource) {
-        try {
-            return LayoutPullParser.createFromFile(new File(layoutResource.getValue()));
-        } catch (FileNotFoundException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
-            ResourceReference itemRef, int fullPosition, int positionPerType,
-            int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
-            ViewAttribute viewAttribute, Object defaultValue) {
-        return null;
-    }
-
-    @Override
-    public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
-            Object viewObject) {
-        return null;
-    }
-
-    @Override
-    public ActionBarCallback getActionBarCallback() {
-        return mActionBarCallback;
-    }
-
-    @Override
-    public boolean supports(int ideFeature) {
-        return false;
-    }
-
-    @NonNull
-    @Override
-    public ParserFactory getParserFactory() {
-        return new ParserFactory() {
-            @NonNull
-            @Override
-            public XmlPullParser createParser(@Nullable String debugName)
-                    throws XmlPullParserException {
-                return new KXmlParser();
-            }
-        };
-    }
-
-    @Override
-    public <T> T getFlag(Key<T> key) {
-        if (key.equals(RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE)) {
-            return (T) PACKAGE_NAME;
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
deleted file mode 100644
index 526613f..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.setup;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.NonNull;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOError;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.android.SdkConstants.ATTR_IGNORE;
-import static com.android.SdkConstants.EXPANDABLE_LIST_VIEW;
-import static com.android.SdkConstants.GRID_VIEW;
-import static com.android.SdkConstants.LIST_VIEW;
-import static com.android.SdkConstants.SPINNER;
-import static com.android.SdkConstants.TOOLS_URI;
-
-public class LayoutPullParser extends KXmlParser implements ILayoutPullParser{
-    @NonNull
-    public static LayoutPullParser createFromFile(@NonNull File layoutFile)
-            throws FileNotFoundException {
-        return new LayoutPullParser(new FileInputStream(layoutFile));
-    }
-
-    /**
-     * @param layoutPath Must start with '/' and be relative to test resources.
-     */
-    @NonNull
-    public static LayoutPullParser createFromPath(@NonNull String layoutPath) {
-        if (layoutPath.startsWith("/")) {
-            layoutPath = layoutPath.substring(1);
-        }
-
-        return new LayoutPullParser(LayoutPullParser.class.getClassLoader().getResourceAsStream
-                (layoutPath));
-    }
-
-    @NonNull
-    public static LayoutPullParser createFromString(@NonNull String contents) {
-        return new LayoutPullParser(new ByteArrayInputStream(
-                contents.getBytes(Charset.forName("UTF-8"))));
-    }
-
-    private LayoutPullParser(@NonNull InputStream inputStream) {
-        try {
-            setFeature(FEATURE_PROCESS_NAMESPACES, true);
-            setInput(inputStream, null);
-        } catch (XmlPullParserException e) {
-            throw new IOError(e);
-        }
-    }
-
-    @Override
-    public Object getViewCookie() {
-        // TODO: Implement this properly.
-        String name = super.getName();
-        if (name == null) {
-            return null;
-        }
-
-        // Store tools attributes if this looks like a layout we'll need adapter view
-        // bindings for in the LayoutlibCallback.
-        if (LIST_VIEW.equals(name) || EXPANDABLE_LIST_VIEW.equals(name) || GRID_VIEW.equals(name) || SPINNER.equals(name)) {
-            Map<String, String> map = null;
-            int count = getAttributeCount();
-            for (int i = 0; i < count; i++) {
-                String namespace = getAttributeNamespace(i);
-                if (namespace != null && namespace.equals(TOOLS_URI)) {
-                    String attribute = getAttributeName(i);
-                    if (attribute.equals(ATTR_IGNORE)) {
-                        continue;
-                    }
-                    if (map == null) {
-                        map = new HashMap<String, String>(4);
-                    }
-                    map.put(attribute, getAttributeValue(i));
-                }
-            }
-
-            return map;
-        }
-
-        return null;
-    }
-
-    @Override
-    @Deprecated
-    public ILayoutPullParser getParser(String layoutName) {
-        // Studio returns null.
-        return null;
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
deleted file mode 100644
index cdf5633..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import android.annotation.NonNull;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-import static java.awt.RenderingHints.*;
-import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
-import static java.io.File.separatorChar;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-
-// Adapted by taking the relevant pieces of code from the following classes:
-//
-// com.android.tools.idea.rendering.ImageUtils,
-// com.android.tools.idea.tests.gui.framework.fixture.layout.ImageFixture and
-// com.android.tools.idea.rendering.RenderTestBase
-/**
- * Utilities related to image processing.
- */
-public class ImageUtils {
-    /**
-     * Normally, this test will fail when there is a missing thumbnail. However, when
-     * you create creating a new test, it's useful to be able to turn this off such that
-     * you can generate all the missing thumbnails in one go, rather than having to run
-     * the test repeatedly to get to each new render assertion generating its thumbnail.
-     */
-    private static final boolean FAIL_ON_MISSING_THUMBNAIL = true;
-
-    private static final int THUMBNAIL_SIZE = 1000;
-
-    private static final double MAX_PERCENT_DIFFERENCE = 0.3;
-
-    public static void requireSimilar(@NonNull String relativePath, @NonNull BufferedImage image)
-            throws IOException {
-        int maxDimension = Math.max(image.getWidth(), image.getHeight());
-        double scale = THUMBNAIL_SIZE / (double)maxDimension;
-        BufferedImage thumbnail = scale(image, scale, scale);
-
-        InputStream is = ImageUtils.class.getClassLoader().getResourceAsStream(relativePath);
-        if (is == null) {
-            String message = "Unable to load golden thumbnail: " + relativePath + "\n";
-            message = saveImageAndAppendMessage(thumbnail, message, relativePath);
-            if (FAIL_ON_MISSING_THUMBNAIL) {
-                fail(message);
-            } else {
-                System.out.println(message);
-            }
-        }
-        else {
-            try {
-                BufferedImage goldenImage = ImageIO.read(is);
-                assertImageSimilar(relativePath, goldenImage, thumbnail, MAX_PERCENT_DIFFERENCE);
-            } finally {
-                is.close();
-            }
-        }
-    }
-
-    public static void assertImageSimilar(String relativePath, BufferedImage goldenImage,
-            BufferedImage image, double maxPercentDifferent) throws IOException {
-        assertEquals("Only TYPE_INT_ARGB image types are supported",  TYPE_INT_ARGB, image.getType());
-
-        if (goldenImage.getType() != TYPE_INT_ARGB) {
-            BufferedImage temp = new BufferedImage(goldenImage.getWidth(), goldenImage.getHeight(),
-                    TYPE_INT_ARGB);
-            temp.getGraphics().drawImage(goldenImage, 0, 0, null);
-            goldenImage = temp;
-        }
-        assertEquals(TYPE_INT_ARGB, goldenImage.getType());
-
-        int imageWidth = Math.min(goldenImage.getWidth(), image.getWidth());
-        int imageHeight = Math.min(goldenImage.getHeight(), image.getHeight());
-
-        // Blur the images to account for the scenarios where there are pixel
-        // differences
-        // in where a sharp edge occurs
-        // goldenImage = blur(goldenImage, 6);
-        // image = blur(image, 6);
-
-        int width = 3 * imageWidth;
-        @SuppressWarnings("UnnecessaryLocalVariable")
-        int height = imageHeight; // makes code more readable
-        BufferedImage deltaImage = new BufferedImage(width, height, TYPE_INT_ARGB);
-        Graphics g = deltaImage.getGraphics();
-
-        // Compute delta map
-        long delta = 0;
-        for (int y = 0; y < imageHeight; y++) {
-            for (int x = 0; x < imageWidth; x++) {
-                int goldenRgb = goldenImage.getRGB(x, y);
-                int rgb = image.getRGB(x, y);
-                if (goldenRgb == rgb) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                // If the pixels have no opacity, don't delta colors at all
-                if (((goldenRgb & 0xFF000000) == 0) && (rgb & 0xFF000000) == 0) {
-                    deltaImage.setRGB(imageWidth + x, y, 0x00808080);
-                    continue;
-                }
-
-                int deltaR = ((rgb & 0xFF0000) >>> 16) - ((goldenRgb & 0xFF0000) >>> 16);
-                int newR = 128 + deltaR & 0xFF;
-                int deltaG = ((rgb & 0x00FF00) >>> 8) - ((goldenRgb & 0x00FF00) >>> 8);
-                int newG = 128 + deltaG & 0xFF;
-                int deltaB = (rgb & 0x0000FF) - (goldenRgb & 0x0000FF);
-                int newB = 128 + deltaB & 0xFF;
-
-                int avgAlpha = ((((goldenRgb & 0xFF000000) >>> 24)
-                        + ((rgb & 0xFF000000) >>> 24)) / 2) << 24;
-
-                int newRGB = avgAlpha | newR << 16 | newG << 8 | newB;
-                deltaImage.setRGB(imageWidth + x, y, newRGB);
-
-                delta += Math.abs(deltaR);
-                delta += Math.abs(deltaG);
-                delta += Math.abs(deltaB);
-            }
-        }
-
-        // 3 different colors, 256 color levels
-        long total = imageHeight * imageWidth * 3L * 256L;
-        float percentDifference = (float) (delta * 100 / (double) total);
-
-        String error = null;
-        String imageName = getName(relativePath);
-        if (percentDifference > maxPercentDifferent) {
-            error = String.format("Images differ (by %.1f%%)", percentDifference);
-        } else if (Math.abs(goldenImage.getWidth() - image.getWidth()) >= 2) {
-            error = "Widths differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        } else if (Math.abs(goldenImage.getHeight() - image.getHeight()) >= 2) {
-            error = "Heights differ too much for " + imageName + ": " +
-                    goldenImage.getWidth() + "x" + goldenImage.getHeight() +
-                    "vs" + image.getWidth() + "x" + image.getHeight();
-        }
-
-        assertEquals(TYPE_INT_ARGB, image.getType());
-        if (error != null) {
-            // Expected on the left
-            // Golden on the right
-            g.drawImage(goldenImage, 0, 0, null);
-            g.drawImage(image, 2 * imageWidth, 0, null);
-
-            // Labels
-            if (imageWidth > 80) {
-                g.setColor(Color.RED);
-                g.drawString("Expected", 10, 20);
-                g.drawString("Actual", 2 * imageWidth + 10, 20);
-            }
-
-            File output = new File(getFailureDir(), "delta-" + imageName);
-            if (output.exists()) {
-                boolean deleted = output.delete();
-                assertTrue(deleted);
-            }
-            ImageIO.write(deltaImage, "PNG", output);
-            error += " - see details in " + output.getPath() + "\n";
-            error = saveImageAndAppendMessage(image, error, relativePath);
-            System.out.println(error);
-            fail(error);
-        }
-
-        g.dispose();
-    }
-
-    /**
-     * Resize the given image
-     *
-     * @param source the image to be scaled
-     * @param xScale x scale
-     * @param yScale y scale
-     * @return the scaled image
-     */
-    @NonNull
-    public static BufferedImage scale(@NonNull BufferedImage source, double xScale, double yScale) {
-
-        int sourceWidth = source.getWidth();
-        int sourceHeight = source.getHeight();
-        int destWidth = Math.max(1, (int) (xScale * sourceWidth));
-        int destHeight = Math.max(1, (int) (yScale * sourceHeight));
-        int imageType = source.getType();
-        if (imageType == BufferedImage.TYPE_CUSTOM) {
-            imageType = BufferedImage.TYPE_INT_ARGB;
-        }
-        if (xScale > 0.5 && yScale > 0.5) {
-            BufferedImage scaled =
-                    new BufferedImage(destWidth, destHeight, imageType);
-            Graphics2D g2 = scaled.createGraphics();
-            g2.setComposite(AlphaComposite.Src);
-            g2.setColor(new Color(0, true));
-            g2.fillRect(0, 0, destWidth, destHeight);
-            if (xScale == 1 && yScale == 1) {
-                g2.drawImage(source, 0, 0, null);
-            } else {
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, destWidth, destHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-            }
-            g2.dispose();
-            return scaled;
-        } else {
-            // When creating a thumbnail, using the above code doesn't work very well;
-            // you get some visible artifacts, especially for text. Instead use the
-            // technique of repeatedly scaling the image into half; this will cause
-            // proper averaging of neighboring pixels, and will typically (for the kinds
-            // of screen sizes used by this utility method in the layout editor) take
-            // about 3-4 iterations to get the result since we are logarithmically reducing
-            // the size. Besides, each successive pass in operating on much fewer pixels
-            // (a reduction of 4 in each pass).
-            //
-            // However, we may not be resizing to a size that can be reached exactly by
-            // successively diving in half. Therefore, once we're within a factor of 2 of
-            // the final size, we can do a resize to the exact target size.
-            // However, we can get even better results if we perform this final resize
-            // up front. Let's say we're going from width 1000 to a destination width of 85.
-            // The first approach would cause a resize from 1000 to 500 to 250 to 125, and
-            // then a resize from 125 to 85. That last resize can distort/blur a lot.
-            // Instead, we can start with the destination width, 85, and double it
-            // successfully until we're close to the initial size: 85, then 170,
-            // then 340, and finally 680. (The next one, 1360, is larger than 1000).
-            // So, now we *start* the thumbnail operation by resizing from width 1000 to
-            // width 680, which will preserve a lot of visual details such as text.
-            // Then we can successively resize the image in half, 680 to 340 to 170 to 85.
-            // We end up with the expected final size, but we've been doing an exact
-            // divide-in-half resizing operation at the end so there is less distortion.
-
-            int iterations = 0; // Number of halving operations to perform after the initial resize
-            int nearestWidth = destWidth; // Width closest to source width that = 2^x, x is integer
-            int nearestHeight = destHeight;
-            while (nearestWidth < sourceWidth / 2) {
-                nearestWidth *= 2;
-                nearestHeight *= 2;
-                iterations++;
-            }
-
-            BufferedImage scaled = new BufferedImage(nearestWidth, nearestHeight, imageType);
-
-            Graphics2D g2 = scaled.createGraphics();
-            setRenderingHints(g2);
-            g2.drawImage(source, 0, 0, nearestWidth, nearestHeight, 0, 0, sourceWidth, sourceHeight,
-                    null);
-            g2.dispose();
-
-            sourceWidth = nearestWidth;
-            sourceHeight = nearestHeight;
-            source = scaled;
-
-            for (int iteration = iterations - 1; iteration >= 0; iteration--) {
-                int halfWidth = sourceWidth / 2;
-                int halfHeight = sourceHeight / 2;
-                scaled = new BufferedImage(halfWidth, halfHeight, imageType);
-                g2 = scaled.createGraphics();
-                setRenderingHints(g2);
-                g2.drawImage(source, 0, 0, halfWidth, halfHeight, 0, 0, sourceWidth, sourceHeight,
-                        null);
-                g2.dispose();
-
-                sourceWidth = halfWidth;
-                sourceHeight = halfHeight;
-                source = scaled;
-                iterations--;
-            }
-            return scaled;
-        }
-    }
-
-    private static void setRenderingHints(@NonNull Graphics2D g2) {
-        g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
-        g2.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY);
-        g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
-    }
-
-    /**
-     * Directory where to write the thumbnails and deltas.
-     */
-    @NonNull
-    private static File getFailureDir() {
-        String workingDirString = System.getProperty("user.dir");
-        File failureDir = new File(workingDirString, "out/failures");
-
-        //noinspection ResultOfMethodCallIgnored
-        failureDir.mkdirs();
-        return failureDir; //$NON-NLS-1$
-    }
-
-    /**
-     * Saves the generated thumbnail image and appends the info message to an initial message
-     */
-    @NonNull
-    private static String saveImageAndAppendMessage(@NonNull BufferedImage image,
-            @NonNull String initialMessage, @NonNull String relativePath) throws IOException {
-        File output = new File(getFailureDir(), getName(relativePath));
-        if (output.exists()) {
-            boolean deleted = output.delete();
-            assertTrue(deleted);
-        }
-        ImageIO.write(image, "PNG", output);
-        initialMessage += "Thumbnail for current rendering stored at " + output.getPath();
-//        initialMessage += "\nRun the following command to accept the changes:\n";
-//        initialMessage += String.format("mv %1$s %2$s", output.getPath(),
-//                ImageUtils.class.getResource(relativePath).getPath());
-        // The above has been commented out, since the destination path returned is in out dir
-        // and it makes the tests pass without the code being actually checked in.
-        return initialMessage;
-    }
-
-    private static String getName(@NonNull String relativePath) {
-        return relativePath.substring(relativePath.lastIndexOf(separatorChar) + 1);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
deleted file mode 100644
index da360f3..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import libcore.io.Streams;
-
-/**
- * Module class loader that loads classes from the test project.
- */
-public class ModuleClassLoader extends ClassLoader {
-    private final Map<String, Class<?>> mClasses = new HashMap<>();
-    private String myModuleRoot;
-
-    /**
-     * @param moduleRoot The path to the module root
-     * @param parent The parent class loader
-     */
-    public ModuleClassLoader(String moduleRoot, ClassLoader parent) {
-        super(parent);
-        myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/");
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        try {
-            return super.findClass(name);
-        } catch (ClassNotFoundException ignored) {
-        }
-
-        Class<?> clazz = mClasses.get(name);
-        if (clazz == null) {
-            String path = name.replace('.', '/').concat(".class");
-            try {
-                byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path));
-                clazz = defineClass(name, b, 0, b.length);
-                mClasses.put(name, clazz);
-            } catch (IOException ignore) {
-                throw new ClassNotFoundException(name + " not found");
-            }
-        }
-
-        return clazz;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
deleted file mode 100644
index 0856ac9..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * {@link AssetRepository} used for render tests.
- */
-public class TestAssetRepository extends AssetRepository {
-    private static InputStream open(String path) throws FileNotFoundException {
-        File asset = new File(path);
-        if (asset.isFile()) {
-            return new FileInputStream(asset);
-        }
-
-        return null;
-    }
-
-    @Override
-    public boolean isSupported() {
-        return true;
-    }
-
-    @Override
-    public InputStream openAsset(String path, int mode) throws IOException {
-        return open(path);
-    }
-
-    @Override
-    public InputStream openNonAsset(int cookie, String path, int mode) throws IOException {
-        return open(path);
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
deleted file mode 100644
index 1df8e79..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util;
-
-import java.lang.ref.WeakReference;
-
-public class TestUtils {
-    public static void gc() {
-        // See RuntimeUtil#gc in jlibs (http://jlibs.in/)
-        Object obj = new Object();
-        WeakReference ref = new WeakReference<>(obj);
-        //noinspection UnusedAssignment
-        obj = null;
-        while (ref.get() != null) {
-            System.gc();
-            System.runFinalization();
-        }
-
-        System.gc();
-        System.runFinalization();
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
deleted file mode 100644
index ee98b4b..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util.perf;
-
-import android.annotation.NonNull;
-import android.util.LongArray;
-
-import java.util.Arrays;
-import java.util.function.LongConsumer;
-
-/**
- * Class that collect a series of longs and produces the median, min and max values.
- */
-public class LongStatsCollector implements LongConsumer {
-    private final LongArray mAllValues;
-    private long mMin = Long.MAX_VALUE;
-    private long mMax = Long.MIN_VALUE;
-    public LongStatsCollector(int estimatedRuns) {
-        mAllValues = new LongArray(estimatedRuns);
-    }
-
-    public int size() {
-        return mAllValues.size();
-    }
-
-    @NonNull
-    public Stats getStats() {
-        if (mAllValues.size() == 0) {
-            throw new IndexOutOfBoundsException("No data");
-        }
-
-        double median;
-        int size = mAllValues.size();
-        long[] buffer = new long[size];
-        for (int i = 0; i < size; i++) {
-            buffer[i] = mAllValues.get(i);
-        }
-
-        Arrays.sort(buffer);
-
-        int midPoint = size / 2;
-        median = (size % 2 == 0) ? (buffer[midPoint - 1] + buffer[midPoint]) / 2 : buffer[midPoint];
-
-        return new Stats(mAllValues.size(), mMin, mMax, median);
-    }
-
-    @Override
-    public void accept(long value) {
-        mMin = Math.min(mMin, value);
-        mMax = Math.max(mMax, value);
-        mAllValues.add(value);
-    }
-
-    public static class Stats {
-        private final int mSamples;
-        private final long mMin;
-        private final long mMax;
-        private final double mMedian;
-
-        private Stats(int samples, long min, long max, double median) {
-            mSamples = samples;
-            mMin = min;
-            mMax = max;
-            mMedian = median;
-        }
-
-        public int getSampleCount() {
-            return mSamples;
-        }
-
-        public long getMin() {
-            return mMin;
-        }
-
-        public long getMax() {
-            return mMax;
-        }
-
-        public double getMedian() {
-            return mMedian;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
deleted file mode 100644
index 7225a10..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util.perf;
-
-import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * JUnit {@link Runner} that times the test execution and produces some stats.
- */
-public class PerformanceRunner extends BlockJUnit4ClassRunner {
-    private static final int DEFAULT_WARMUP_ITERATIONS = 50;
-    private static final int DEFAULT_RUNS = 100;
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-
-    public PerformanceRunner(Class<?> testClass) throws InitializationError {
-        super(testClass);
-
-        Configuration classConfig = testClass.getAnnotation(Configuration.class);
-        mWarmUpIterations = classConfig != null && classConfig.warmUpIterations() != -1 ?
-                classConfig.warmUpIterations() :
-                DEFAULT_WARMUP_ITERATIONS;
-        mRuns = classConfig != null && classConfig.runs() != -1 ?
-                classConfig.runs() :
-                DEFAULT_RUNS;
-    }
-
-    @Override
-    protected Statement methodInvoker(FrameworkMethod method, Object test) {
-        int warmUpIterations;
-        int runs;
-
-        Configuration methodConfig = method.getAnnotation(Configuration.class);
-        warmUpIterations = methodConfig != null && methodConfig.warmUpIterations() != -1 ?
-                methodConfig.warmUpIterations() :
-                mWarmUpIterations;
-        runs = methodConfig != null && methodConfig.runs() != -1 ?
-                methodConfig.runs() :
-                mRuns;
-        return new TimedStatement(super.methodInvoker(method, test), warmUpIterations, runs,
-                (result) -> System.out.println(result.toString()));
-    }
-
-    @Override
-    public void run(RunNotifier notifier) {
-        super.run(notifier);
-    }
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Inherited
-    public @interface Configuration {
-        int warmUpIterations() default -1;
-
-        int runs() default -1;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
deleted file mode 100644
index 77a2b0e..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.TestUtils;
-
-import org.junit.runners.model.Statement;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-/**
- * JUnit {@link Statement} used to measure some statistics about the test method.
- */
-public class TimedStatement extends Statement {
-    private static final int CALIBRATION_WARMUP_ITERATIONS = 50;
-    private static final int CALIBRATION_RUNS = 100;
-
-    private static boolean sIsCalibrated;
-    private static double sCalibrated;
-
-    private final Statement mStatement;
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final Runtime mRuntime = Runtime.getRuntime();
-    private final Consumer<TimedStatementResult> mCallback;
-
-    TimedStatement(Statement statement, int warmUpIterations, int runs,
-            Consumer<TimedStatementResult> finishedCallback) {
-        mStatement = statement;
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCallback = finishedCallback;
-    }
-
-    /**
-     * The calibrate method tries to do some work that involves IO, memory allocations and some
-     * operations on the randomly generated data to calibrate the speed of the machine with
-     * something that resembles the execution of a test case.
-     */
-    private static void calibrateMethod() throws IOException {
-        File tmpFile = File.createTempFile("test", "file");
-        Random rnd = new Random();
-        HashFunction hashFunction = Hashing.sha512();
-        for (int i = 0; i < 5 + rnd.nextInt(5); i++) {
-            FileOutputStream stream = new FileOutputStream(tmpFile);
-            int bytes = 30000 + rnd.nextInt(60000);
-            byte[] buffer = new byte[bytes];
-
-            rnd.nextBytes(buffer);
-            byte acc = 0;
-            for (int j = 0; j < bytes; j++) {
-                acc += buffer[i];
-            }
-            buffer[0] = acc;
-            stream.write(buffer);
-            System.gc();
-            stream.close();
-            FileInputStream input = new FileInputStream(tmpFile);
-            byte[] readBuffer = new byte[bytes];
-            //noinspection ResultOfMethodCallIgnored
-            input.read(readBuffer);
-            buffer = readBuffer;
-            HashCode code1 = hashFunction.hashBytes(buffer);
-            Arrays.sort(buffer);
-            HashCode code2 = hashFunction.hashBytes(buffer);
-            input.close();
-
-            FileOutputStream hashStream = new FileOutputStream(tmpFile);
-            hashStream.write(code1.asBytes());
-            hashStream.write(code2.asBytes());
-            hashStream.close();
-        }
-    }
-
-    /**
-     * Runs the calibration process and sets the calibration measure in {@link #sCalibrated}
-     */
-    private static void doCalibration() throws IOException {
-        System.out.println("Calibrating ...");
-        TestUtils.gc();
-        for (int i = 0; i < CALIBRATION_WARMUP_ITERATIONS; i++) {
-            calibrateMethod();
-        }
-
-        LongStatsCollector stats = new LongStatsCollector(CALIBRATION_RUNS);
-        for (int i = 0; i < CALIBRATION_RUNS; i++) {
-            TestUtils.gc();
-            long start = System.currentTimeMillis();
-            calibrateMethod();
-            stats.accept(System.currentTimeMillis() - start);
-        }
-
-        sCalibrated = stats.getStats().getMedian();
-        sIsCalibrated = true;
-        System.out.printf("  DONE %fms\n", sCalibrated);
-    }
-
-    private long getUsedMemory() {
-        return mRuntime.totalMemory() - mRuntime.freeMemory();
-    }
-
-
-    @Override
-    public void evaluate() throws Throwable {
-        if (!sIsCalibrated) {
-            doCalibration();
-        }
-
-        for (int i = 0; i < mWarmUpIterations; i++) {
-            mStatement.evaluate();
-        }
-
-        LongStatsCollector timeStats = new LongStatsCollector(mRuns);
-        LongStatsCollector memoryUseStats = new LongStatsCollector(mRuns);
-        AtomicBoolean collectSamples = new AtomicBoolean(false);
-
-        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
-        TestUtils.gc();
-        executorService.scheduleAtFixedRate(() -> {
-            if (!collectSamples.get()) {
-                return;
-            }
-            memoryUseStats.accept(getUsedMemory());
-        }, 0, 200, TimeUnit.MILLISECONDS);
-
-        try {
-            for (int i = 0; i < mRuns; i++) {
-                TestUtils.gc();
-                collectSamples.set(true);
-                long startTimeMs = System.currentTimeMillis();
-                mStatement.evaluate();
-                long stopTimeMs = System.currentTimeMillis();
-                collectSamples.set(true);
-                timeStats.accept(stopTimeMs - startTimeMs);
-
-            }
-        } finally {
-            executorService.shutdownNow();
-        }
-
-        TimedStatementResult result = new TimedStatementResult(
-                mWarmUpIterations,
-                mRuns,
-                sCalibrated,
-                timeStats.getStats(),
-                memoryUseStats.getStats());
-        mCallback.accept(result);
-    }
-
-}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
deleted file mode 100644
index 59f90d2..0000000
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.intensive.util.perf;
-
-import com.android.layoutlib.bridge.intensive.util.perf.LongStatsCollector.Stats;
-
-import java.text.DecimalFormat;
-
-/**
- * Result value of a {@link TimedStatement}
- */
-public class TimedStatementResult {
-    private static final DecimalFormat UNITS_FORMAT = new DecimalFormat("#.##");
-
-    private final int mWarmUpIterations;
-    private final int mRuns;
-    private final double mCalibrationTimeMs;
-    private final Stats mTimeStats;
-    private final Stats mMemoryStats;
-
-    TimedStatementResult(int warmUpIterations, int runs,
-            double calibrationTimeMs,
-            Stats timeStats,
-            Stats memoryStats) {
-        mWarmUpIterations = warmUpIterations;
-        mRuns = runs;
-        mCalibrationTimeMs = calibrationTimeMs;
-        mTimeStats = timeStats;
-        mMemoryStats = memoryStats;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "Warm up %d. Runs %d\n" + "Time:             %s ms (min: %s, max %s)\n" +
-                        "Calibration Time: %f ms\n" +
-                        "Calibrated Time:  %s units (min: %s, max %s)\n" +
-                        "Sampled %d times\n" +
-                        "   Memory used:  %d bytes (max %d)\n\n",
-                mWarmUpIterations, mRuns,
-                mTimeStats.getMedian(), mTimeStats.getMin(), mTimeStats.getMax(),
-                mCalibrationTimeMs,
-                UNITS_FORMAT.format((mTimeStats.getMedian() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMin() / mCalibrationTimeMs) * 100000),
-                UNITS_FORMAT.format((mTimeStats.getMax() / mCalibrationTimeMs) * 100000),
-                mMemoryStats.getSampleCount(),
-                (long)mMemoryStats.getMedian() - mMemoryStats.getMin(),
-                mMemoryStats.getMax() - mMemoryStats.getMin());
-    }
-}
diff --git a/tools/layoutlib/bridge/update_nav_icons.sh b/tools/layoutlib/bridge/update_nav_icons.sh
deleted file mode 100755
index 7030d19..0000000
--- a/tools/layoutlib/bridge/update_nav_icons.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-# copies the navigation bar icons from system ui code to layoutlib.
-# to run, simply execute the script. (if not using bash, cd to the dir
-# containing this script and then run by ./update_nav_icons.sh)
-
-# Try to get the location of this script.
-if [ -n $BASH ]; then
-  # see http://stackoverflow.com/a/246128/1546000
-  MY_LOCATION=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-  cd $MY_LOCATION
-else
-  # Let's assume script was run from the same dir.
-  MY_LOCATION=$(pwd)
-fi
-
-# Check mac or linux to get sed argument to enable extended regex.
-case $(uname -s) in
-  Darwin)
-    EXT_REGEX="-E"
-    ;;
-  *)
-    EXT_REGEX="-r"
-    ;;
-esac
-
-
-FB="frameworks/base"
-# frameworks/base relative to current location
-FB=$(echo $MY_LOCATION | sed $EXT_REGEX -e "s,.*$FB[^/]*/,," -e "s,[^/]+,..,g")
-CURRENT_API=21  # update only if icons change from this api version.
-DENSITIES="ldpi mdpi hdpi xhdpi xxhdpi"
-ICONS="ic_sysbar_back.png ic_sysbar_home.png ic_sysbar_recent.png"
-BARS="./resources/bars/"
-
-for icon in $ICONS
-do
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/$density/"
-    mkdir -p "$destination"  # create if not present.
-    cp -v "$FB/packages/SystemUI/res/drawable-$density/$icon" "$destination"
-  done
-
-  for density in $DENSITIES
-  do
-    destination="$BARS/v$CURRENT_API/ldrtl-$density/"
-    mkdir -p "$destination"
-    cp -v "$FB/packages/SystemUI/res/drawable-ldrtl-$density/$icon" "$destination"
-    done
-done
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
deleted file mode 100644
index 25c3b3e..0000000
--- a/tools/layoutlib/create/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry excluding="mock_data/" kind="src" path="tests"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/asm/asm-4.0.jar" sourcepath="/ANDROID_PLAT_SRC/prebuilts/misc/common/asm/src.zip"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/layoutlib/create/.project b/tools/layoutlib/create/.project
deleted file mode 100644
index e100d17..0000000
--- a/tools/layoutlib/create/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>layoutlib_create</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/tools/layoutlib/create/.settings/README.txt b/tools/layoutlib/create/.settings/README.txt
deleted file mode 100644
index 9120b20..0000000
--- a/tools/layoutlib/create/.settings/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Copy this in eclipse project as a .settings folder at the root.
-This ensure proper compilation compliance and warning/error levels.
\ No newline at end of file
diff --git a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs b/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 5381a0e..0000000
--- a/tools/layoutlib/create/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,93 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled
-org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=error
-org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
-org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
deleted file mode 100644
index 7611cde..0000000
--- a/tools/layoutlib/create/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAR_MANIFEST := manifest.txt
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	asm-5.2
-
-LOCAL_MODULE := layoutlib_create
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
deleted file mode 100644
index 727b194..0000000
--- a/tools/layoutlib/create/README.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-
-
-- Description -
----------------
-
-Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor to perform
-layout.
-
-
-- Usage -
----------
-
- ./layoutlib_create destination.jar path/to/android1.jar path/to/android2.jar
-
-
-- Design Overview -
--------------------
-
-Layoutlib_create uses a few jars from the framework containing the Java code used by Android as
-generated by the Android build, right before the classes are converted to a DEX format.
-
-These jars can't be used directly in Eclipse as:
-- they contains references to native code (which we want to avoid in Eclipse),
-- some classes need to be overridden, for example all the drawing code that is replaced by Java 2D
-  calls in Eclipse.
-- some of the classes that need to be changed are final and/or we need access to their private
-  internal state.
-
-Consequently this tool:
-- parses the input JAR,
-- modifies some of the classes directly using some bytecode manipulation,
-- filters some packages and removes those we don't want in the output JAR,
-- injects some new classes,
-- generates a modified JAR file that is suitable for the Android plugin for Eclipse to perform
-  rendering.
-
-The ASM library is used to do the bytecode modification using its visitor pattern API.
-
-The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the configuration
-is done in the main() method and the CreateInfo structure is expected to change with the Android
-platform as new classes are added, changed or removed. Some configuration that may be platform
-dependent is also present elsewhere in code.
-
-The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the platform, that
-provides all the necessary missing implementation for rendering graphics in Eclipse.
-
-
-
-- Implementation Notes -
-------------------------
-
-The tool works in two phases:
-- first analyze the input jar (AsmAnalyzer class)
-- then generate the output jar (AsmGenerator class),
-
-
-- Analyzer
-----------
-
-The goal of the analyzer is to create a graph of all the classes from the input JAR with their
-dependencies and then only keep the ones we want.
-
-To do that, the analyzer is created with a list of base classes to keep -- everything that derives
-from these is kept. Currently the one such class is android.view.View: since we want to render
-layouts, anything that is sort of a view needs to be kept.
-
-The analyzer is also given a list of class names to keep in the output. This is done using
-shell-like glob patterns that filter on the fully-qualified class names, for example "android.*.R**"
-("*" does not matches dots whilst "**" does, and "." and "$" are interpreted as-is). In practice we
-almost but not quite request the inclusion of full packages.
-
-The analyzer is also given a list of classes to exclude. A fake implementation of these classes is
-injected by the Generator.
-
-With this information, the analyzer parses the input zip to find all the classes. All classes
-deriving from the requested bases classes are kept. All classes whose name match the glob pattern
-are kept. The analysis then finds all the dependencies of the classes that are to be kept using an
-ASM visitor on the class, the field types, the method types and annotations types. Classes that
-belong to the current JRE are excluded.
-
-The output of the analyzer is a set of ASM ClassReader instances which are then fed to the
-generator.
-
-
-- Generator
------------
-
-The generator is constructed from a CreateInfo struct that acts as a config file and lists:
-- the classes to inject in the output JAR -- these classes are directly implemented in
-  layoutlib_create and will be used to interface with the renderer in Eclipse.
-- specific methods to override (see method stubs details below).
-- specific methods for which to delegate calls.
-- specific methods to remove based on their return type.
-- specific classes to rename.
-- specific classes to refactor.
-
-Each of these are specific strategies we use to be able to modify the Android code to fit within the
-Eclipse renderer. These strategies are explained below.
-
-The core method of the generator is transform(): it takes an input ASM ClassReader and modifies it
-to produce a byte array suitable for the final JAR file.
-
-The first step of the transformation is to implement the method delegates.
-
-The TransformClassAdapter is then used to process the potentially renamed class.  All protected or
-private classes are market as public. All classes are made non-final. Interfaces are left as-is.
-
-If a method has a return type that must be erased, the whole method is skipped.  Methods are also
-changed from protected/private to public. The code of the methods is then kept as-is, except for
-native methods which are replaced by a stub. Methods that are to be overridden are also replaced by
-a stub.
-
-Finally fields are also visited and changed from protected/private to public.
-
-The next step of the transformation is changing the name of the class in case we requested the class
-to be renamed. This uses the RenameClassAdapter to also rename all inner classes and references in
-methods and types. Note that other classes are not transformed and keep referencing the original
-name.
-
-The class is then fed to RefactorClassAdapter which is like RenameClassAdapter but updates the
-references in all classes. This is used to update the references of classes in the java package that
-were added in the Dalvik VM but are not a part of the Desktop VM. The existing classes are
-modified to update all references to these non-desktop classes. An alternate implementation of
-these (com.android.tools.layoutlib.java.*) is injected.
-
-RenameClassAdapter and RefactorClassAdapter both inherit from AbstractClassAdapter which changes the
-class version (version of the JDK used to compile the class) to 50 (corresponding to Java 6), if the
-class was originally compiled with Java 7 (version 51). This is because we don't currently generate
-the StackMapTable correctly and Java 7 VM enforces that classes with version greater than 51 have
-valid StackMapTable. As a side benefit of this, we can continue to support Java 6 because Java 7 on
-Mac has horrible font rendering support.
-
-ReplaceMethodCallsAdapter replaces calls to certain methods. This is different from the
-DelegateMethodAdapter since it doesn't preserve the original copy of the method and more importantly
-changes the calls to a method in each class instead of changing the implementation of the method.
-This is useful for methods in the Java namespace where we cannot add delegates. The configuration
-for this is not done through the CreateInfo class, but done in the ReplaceMethodAdapter.
-
-The ClassAdapters are chained together to achieve the desired output. (Look at section 2.2.7
-Transformation chains in the asm user guide, link in the References.) The order of execution of
-these is:
-ClassReader -> [DelegateClassAdapter] -> TransformClassAdapter -> [RenameClassAdapter] ->
-RefactorClassAdapter -> [ReplaceMethodCallsAdapter] -> ClassWriter
-
-- Method stubs
---------------
-
-As indicated above, all native and overridden methods are replaced by a stub.  We don't have the
-code to replace with in layoutlib_create. Instead the StubMethodAdapter replaces the code of the
-method by a call to OverrideMethod.invokeX(). When using the final JAR, the bridge can register
-listeners from these overridden method calls based on the method signatures.
-
-The listeners are currently pretty basic: we only pass the signature of the method being called, its
-caller object and a flag indicating whether the method was native. We do not currently provide the
-parameters. The listener can however specify the return value of the overridden method.
-
-This strategy is now obsolete and replaced by the method delegates.
-
-
-- Strategies
-------------
-
-We currently have 6 strategies to deal with overriding the rendering code and make it run in
-Eclipse. Most of these strategies are implemented hand-in-hand by the bridge (which runs in Eclipse)
-and the generator.
-
-
-1- Class Injection
-
-This is the easiest: we currently inject the following classes:
-- OverrideMethod and its associated MethodListener and MethodAdapter are used to intercept calls to
-  some specific methods that are stubbed out and change their return value.
-- CreateInfo class, which configured the generator. Not used yet, but could in theory help us track
-  what the generator changed.
-- AutoCloseable and Objects are part of Java 7. To enable us to still run on Java 6, new classes are
-  injected. The implementation for these classes has been taken from Android's libcore
-  (platform/libcore/luni/src/main/java/java/...).
-- Charsets, IntegralToString and UnsafeByteSequence are not part of the Desktop VM. They are
-  added to the Dalvik VM for performance reasons. An implementation that is very close to the
-  original (which is at platform/libcore/luni/src/main/java/...) is injected. Since these classees
-  were in part of the java package, where we can't inject classes, all references to these have been
-  updated (See strategy 4- Refactoring Classes).
-
-
-2- Overriding methods
-
-As explained earlier, the creator doesn't have any replacement code for methods to override. Instead
-it removes the original code and replaces it by a call to a specific OveriddeMethod.invokeX(). The
-bridge then registers a listener on the method signature and can provide an implementation.
-
-This strategy is now obsolete and replaced by the method delegates (See strategy 6- Method
-Delegates).
-
-
-3- Renaming classes
-
-This simply changes the name of a class in its definition, as well as all its references in internal
-inner classes and methods. Calls from other classes are not modified -- they keep referencing the
-original class name. This allows the bridge to literally replace an implementation.
-
-An example will make this easier: android.graphics.Paint is the main drawing class that we need to
-replace. To do so, the generator renames Paint to _original_Paint. Later the bridge provides its own
-replacement version of Paint which will be used by the rest of the Android stack. The replacement
-version of Paint can still use (either by inheritance or delegation) all the original non-native
-code of _original_Paint if it so desires.
-
-Some of the Android classes are basically wrappers over native objects and since we don't have the
-native code in Eclipse, we need to provide a full alternate implementation. Sub-classing doesn't
-work as some native methods are static and we don't control object creation.
-
-This won't rename/replace the inner static methods of a given class.
-
-
-4- Refactoring classes
-
-This is very similar to the Renaming classes except that it also updates the reference in all
-classes. This is done for classes which are added to the Dalvik VM for performance reasons but are
-not present in the Desktop VM. An implementation for these classes is also injected.
-
-
-5- Method erasure based on return type
-
-This is mostly an implementation detail of the bridge: in the Paint class mentioned above, some
-inner static classes are used to pass around attributes (e.g. FontMetrics, or the Style enum) and
-all the original implementation is native.
-
-In this case we have a strategy that tells the generator that anything returning, for example, the
-inner class Paint$Style in the Paint class should be discarded and the bridge will provide its own
-implementation.
-
-
-6- Method Delegates
-
-This strategy is used to override method implementations. Given a method SomeClass.MethodName(), 1
-or 2 methods are generated:
-a- A copy of the original method named SomeClass.MethodName_Original(). The content is the original
-method as-is from the reader. This step is omitted if the method is native, since it has no Java
-implementation.
-b- A brand new implementation of SomeClass.MethodName() which calls to a non-existing static method
-named SomeClass_Delegate.MethodName(). The implementation of this 'delegate' method is done in
-layoutlib_bridge.
-
-The delegate method is a static method. If the original method is non-static, the delegate method
-receives the original 'this' as its first argument. If the original method is an inner non-static
-method, it also receives the inner 'this' as the second argument.
-
-
-
-- References -
---------------
-
-
-The JVM Specification 2nd edition:
-  http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
-
-Understanding bytecode:
-  http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
-
-Bytecode opcode list:
-  http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
-
-ASM user guide:
-  http://download.forge.objectweb.org/asm/asm4-guide.pdf
-
-
---
-end
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
deleted file mode 100644
index ac97502..0000000
--- a/tools/layoutlib/create/create.iml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/data" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/tests/mock_data" type="java-test-resource" />
-      <excludeFolder url="file://$MODULE_DIR$/.settings" />
-    </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="module-library">
-      <library name="asm-5.2">
-        <CLASSES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-5.2.jar!/" />
-        </CLASSES>
-        <JAVADOC />
-        <SOURCES>
-          <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/src.zip!/" />
-        </SOURCES>
-      </library>
-    </orderEntry>
-    <orderEntry type="library" scope="TEST" name="junit" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/create/manifest.txt b/tools/layoutlib/create/manifest.txt
deleted file mode 100644
index 238e7f9..0000000
--- a/tools/layoutlib/create/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.tools.layoutlib.create.Main
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
deleted file mode 100644
index 9a48ea6..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a method that has been converted to a delegate by layoutlib_create.
- */
-@Retention(RetentionPolicy.RUNTIME)
-public @interface LayoutlibDelegate {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
deleted file mode 100644
index 0689c92..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes a parameter or field can be null.
- * <p/>
- * When decorating a method call parameter, this denotes the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically used
- * on optional parameters.
- * <p/>
- * When decorating a method, this denotes the method might legitimately return null.
- * <p/>
- * This is a marker annotation and it has no specific attributes.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface Nullable {
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
deleted file mode 100644
index e4e016b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.SOURCE)
-public @interface VisibleForTesting {
-    /**
-     * Intended visibility if the element had not been made public or package-private for
-     * testing.
-     */
-    enum Visibility {
-        /** The element should be considered protected. */
-        PROTECTED,
-        /** The element should be considered package-private. */
-        PACKAGE,
-        /** The element should be considered private. */
-        PRIVATE
-    }
-
-    /**
-     * Intended visibility if the element had not been made public or package-private for testing.
-     * If not specified, one should assume the element originally intended to be private.
-     */
-    Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
deleted file mode 100644
index 01c940a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AbstractClassAdapter.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-import org.objectweb.asm.signature.SignatureWriter;
-
-/**
- * Provides the common code for RenameClassAdapter and RefactorClassAdapter. It
- * goes through the complete class and finds references to other classes. It
- * then calls {@link #renameInternalType(String)} to convert the className to
- * the new value, if need be.
- */
-public abstract class AbstractClassAdapter extends ClassVisitor {
-
-    /**
-     * Returns the new FQCN for the class, if the reference to this class needs
-     * to be updated. Else, it returns the same string.
-     * @param name Old FQCN
-     * @return New FQCN if it needs to be renamed, else the old FQCN
-     */
-    abstract String renameInternalType(String name);
-
-    public AbstractClassAdapter(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    /**
-     * Renames a type descriptor, e.g. "Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    String renameTypeDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        return renameType(Type.getType(desc));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    String renameType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            return "L" + renameInternalType(in) + ";";
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return sb.toString();
-        }
-        return type.getDescriptor();
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;".
-     * This is like renameType() except that it returns a Type object.
-     * If the type doesn't need to be renamed, returns the input type object.
-     */
-    Type renameTypeAsType(Type type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.getSort() == Type.OBJECT) {
-            String in = type.getInternalName();
-            String newIn = renameInternalType(in);
-            if (!newIn.equals(in)) {
-                return Type.getType("L" + newIn + ";");
-            }
-        } else if (type.getSort() == Type.ARRAY) {
-            StringBuilder sb = new StringBuilder();
-            for (int n = type.getDimensions(); n > 0; n--) {
-                sb.append('[');
-            }
-            sb.append(renameType(type.getElementType()));
-            return Type.getType(sb.toString());
-        }
-        return type;
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    String renameMethodDesc(String desc) {
-        if (desc == null) {
-            return null;
-        }
-
-        Type[] args = Type.getArgumentTypes(desc);
-
-        StringBuilder sb = new StringBuilder("(");
-        for (Type arg : args) {
-            String name = renameType(arg);
-            sb.append(name);
-        }
-        sb.append(')');
-
-        Type ret = Type.getReturnType(desc);
-        String name = renameType(ret);
-        sb.append(name);
-
-        return sb.toString();
-    }
-
-
-    /**
-     * Renames the ClassSignature handled by ClassVisitor.visit
-     * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
-     */
-    String renameTypeSignature(String sig) {
-        if (sig == null) {
-            return null;
-        }
-        SignatureReader reader = new SignatureReader(sig);
-        SignatureWriter writer = new SignatureWriter();
-        reader.accept(new RenameSignatureAdapter(writer));
-        sig = writer.toString();
-        return sig;
-    }
-
-
-    /**
-     * Renames the FieldTypeSignature handled by ClassVisitor.visitField
-     * or MethodVisitor.visitLocalVariable.
-     */
-    String renameFieldSignature(String sig) {
-        return renameTypeSignature(sig);
-    }
-
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        name = renameInternalType(name);
-        superName = renameInternalType(superName);
-        signature = renameTypeSignature(signature);
-        if (interfaces != null) {
-            for (int i = 0; i < interfaces.length; ++i) {
-                interfaces[i] = renameInternalType(interfaces[i]);
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        name = renameInternalType(name);
-        outerName = renameInternalType(outerName);
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        super.visitOuterClass(renameInternalType(owner), name, renameTypeDesc(desc));
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        desc = renameMethodDesc(desc);
-        signature = renameTypeSignature(signature);
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-        return new RenameMethodAdapter(mw);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        desc = renameTypeDesc(desc);
-        return super.visitAnnotation(desc, visible);
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        desc = renameTypeDesc(desc);
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-
-    //----------------------------------
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name.
-     */
-    public class RenameMethodAdapter extends MethodVisitor {
-
-        /**
-         * Creates a method visitor that renames all references from a given old name to a given new
-         * name. The method visitor will also rename all inner classes.
-         * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-         */
-        public RenameMethodAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitAnnotation(desc, visible);
-        }
-
-        @Override
-        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
-            desc = renameTypeDesc(desc);
-
-            return super.visitParameterAnnotation(parameter, desc, visible);
-        }
-
-        @Override
-        public void visitTypeInsn(int opcode, String type) {
-            // The type sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (type.indexOf(';') > 0) {
-                type = renameTypeDesc(type);
-            } else {
-                type = renameInternalType(type);
-            }
-            super.visitTypeInsn(opcode, type);
-        }
-
-        @Override
-        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-            owner = renameInternalType(owner);
-            desc = renameTypeDesc(desc);
-
-            super.visitFieldInsn(opcode, owner, name, desc);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            // The owner sometimes turns out to be a type descriptor. We try to detect it and fix.
-            if (owner.indexOf(';') > 0) {
-                owner = renameTypeDesc(owner);
-            } else {
-                owner = renameInternalType(owner);
-            }
-            desc = renameMethodDesc(desc);
-
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-
-        @Override
-        public void visitLdcInsn(Object cst) {
-            // If cst is a Type, this means the code is trying to pull the .class constant
-            // for this class, so it needs to be renamed too.
-            if (cst instanceof Type) {
-                cst = renameTypeAsType((Type) cst);
-            }
-            super.visitLdcInsn(cst);
-        }
-
-        @Override
-        public void visitMultiANewArrayInsn(String desc, int dims) {
-            desc = renameTypeDesc(desc);
-
-            super.visitMultiANewArrayInsn(desc, dims);
-        }
-
-        @Override
-        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-            type = renameInternalType(type);
-
-            super.visitTryCatchBlock(start, end, handler, type);
-        }
-
-        @Override
-        public void visitLocalVariable(String name, String desc, String signature,
-                Label start, Label end, int index) {
-            desc = renameTypeDesc(desc);
-            signature = renameFieldSignature(signature);
-
-            super.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-
-    }
-
-    //----------------------------------
-
-    public class RenameSignatureAdapter extends SignatureVisitor {
-
-        private final SignatureVisitor mSv;
-
-        public RenameSignatureAdapter(SignatureVisitor sv) {
-            super(Main.ASM_VERSION);
-            mSv = sv;
-        }
-
-        @Override
-        public void visitClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitClassType(name);
-        }
-
-        @Override
-        public void visitInnerClassType(String name) {
-            name = renameInternalType(name);
-            mSv.visitInnerClassType(name);
-        }
-
-        @Override
-        public SignatureVisitor visitArrayType() {
-            SignatureVisitor sv = mSv.visitArrayType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitBaseType(char descriptor) {
-            mSv.visitBaseType(descriptor);
-        }
-
-        @Override
-        public SignatureVisitor visitClassBound() {
-            SignatureVisitor sv = mSv.visitClassBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitEnd() {
-            mSv.visitEnd();
-        }
-
-        @Override
-        public SignatureVisitor visitExceptionType() {
-            SignatureVisitor sv = mSv.visitExceptionType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitFormalTypeParameter(String name) {
-            mSv.visitFormalTypeParameter(name);
-        }
-
-        @Override
-        public SignatureVisitor visitInterface() {
-            SignatureVisitor sv = mSv.visitInterface();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitInterfaceBound() {
-            SignatureVisitor sv = mSv.visitInterfaceBound();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitParameterType() {
-            SignatureVisitor sv = mSv.visitParameterType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitReturnType() {
-            SignatureVisitor sv = mSv.visitReturnType();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public SignatureVisitor visitSuperclass() {
-            SignatureVisitor sv = mSv.visitSuperclass();
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeArgument() {
-            mSv.visitTypeArgument();
-        }
-
-        @Override
-        public SignatureVisitor visitTypeArgument(char wildcard) {
-            SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
-            return new RenameSignatureAdapter(sv);
-        }
-
-        @Override
-        public void visitTypeVariable(String name) {
-            mSv.visitTypeVariable(name);
-        }
-
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
deleted file mode 100644
index 11d4c81..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the desired classes and their dependencies.
- */
-public class AsmAnalyzer {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The input source JAR to parse. */
-    private final List<String> mOsSourceJar;
-    /** The generator to fill with the class list and dependency list. */
-    private final AsmGenerator mGen;
-    /** Keep all classes that derive from these one (these included). */
-    private final String[] mDeriveFrom;
-    /** Glob patterns of classes to keep, e.g. "com.foo.*" */
-    private final String[] mIncludeGlobs;
-    /** The set of classes to exclude.*/
-    private final Set<String> mExcludedClasses;
-    /** Glob patterns of files to keep as is. */
-    private final String[] mIncludeFileGlobs;
-    /** Internal names of classes that contain method calls that need to be rewritten. */
-    private final Set<String> mReplaceMethodCallClasses = new HashSet<>();
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     * @param osJarPath The input source JARs to parse.
-     * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included).
-     * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
-     *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
-     * @param includeFileGlobs Glob patterns of files which are kept as is. This is only for files
-     *        not ending in .class.
-     */
-    public AsmAnalyzer(Log log, List<String> osJarPath, AsmGenerator gen,
-            String[] deriveFrom, String[] includeGlobs, Set<String> excludeClasses,
-            String[] includeFileGlobs) {
-        mLog = log;
-        mGen = gen;
-        mOsSourceJar = osJarPath != null ? osJarPath : new ArrayList<String>();
-        mDeriveFrom = deriveFrom != null ? deriveFrom : new String[0];
-        mIncludeGlobs = includeGlobs != null ? includeGlobs : new String[0];
-        mExcludedClasses = excludeClasses;
-        mIncludeFileGlobs = includeFileGlobs != null ? includeFileGlobs : new String[0];
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     * Fills the generator with classes & dependencies found.
-     */
-    public void analyze() throws IOException, LogAbortException {
-
-        TreeMap<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        parseZip(mOsSourceJar, zipClasses, filesFound);
-        mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
-                mOsSourceJar.size() > 1 ? "s" : "");
-
-        Map<String, ClassReader> found = findIncludes(zipClasses);
-        Map<String, ClassReader> deps = findDeps(zipClasses, found);
-
-        if (mGen != null) {
-            mGen.setKeep(found);
-            mGen.setDeps(deps);
-            mGen.setCopyFiles(filesFound);
-            mGen.setRewriteMethodCallClasses(mReplaceMethodCallClasses);
-        }
-    }
-
-    /**
-     * Parses a JAR file and adds all the classes found to <code>classes</code>
-     * and all other files to <code>filesFound</code>.
-     *
-     * @param classes The map of class name => ASM ClassReader. Class names are
-     *                in the form "android.view.View".
-     * @param filesFound The map of file name => InputStream. The file name is
-     *                  in the form "android/data/dataFile".
-     */
-    void parseZip(List<String> jarPathList, Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-        if (classes == null || filesFound == null) {
-            return;
-        }
-
-        Pattern[] includeFilePatterns = new Pattern[mIncludeFileGlobs.length];
-        for (int i = 0; i < mIncludeFileGlobs.length; ++i) {
-            includeFilePatterns[i] = getPatternFromGlob(mIncludeFileGlobs[i]);
-        }
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    for (Pattern includeFilePattern : includeFilePatterns) {
-                        if (includeFilePattern.matcher(entry.getName()).matches()) {
-                            filesFound.put(entry.getName(), zip.getInputStream(entry));
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Process the "includes" arrays.
-     * <p/>
-     * This updates the in_out_found map.
-     */
-    Map<String, ClassReader> findIncludes(Map<String, ClassReader> zipClasses)
-            throws LogAbortException {
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mLog.debug("Find classes to include.");
-
-        for (String s : mIncludeGlobs) {
-            findGlobs(s, zipClasses, found);
-        }
-        for (String s : mDeriveFrom) {
-            findClassesDerivingFrom(s, zipClasses, found);
-        }
-
-        return found;
-    }
-
-
-    /**
-     * Uses ASM to find the class reader for the given FQCN class name.
-     * If found, insert it in the in_out_found map.
-     * Returns the class reader object.
-     */
-    ClassReader findClass(String className, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        ClassReader classReader = zipClasses.get(className);
-        if (classReader == null) {
-            throw new LogAbortException("Class %s not found by ASM in %s",
-                    className, mOsSourceJar);
-        }
-
-        inOutFound.put(className, classReader);
-        return classReader;
-    }
-
-    /**
-     * Insert in the inOutFound map all classes found in zipClasses that match the
-     * given glob pattern.
-     * <p/>
-     * The glob pattern is not a regexp. It only accepts the "*" keyword to mean
-     * "anything but a period". The "." and "$" characters match themselves.
-     * The "**" keyword means everything including ".".
-     * <p/>
-     * Examples:
-     * <ul>
-     * <li>com.foo.* matches all classes in the package com.foo but NOT sub-packages.
-     * <li>com.foo*.*$Event matches all internal Event classes in a com.foo*.* class.
-     * </ul>
-     */
-    void findGlobs(String globPattern, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-
-        Pattern regexp = getPatternFromGlob(globPattern);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String class_name = entry.getKey();
-            if (regexp.matcher(class_name).matches() &&
-                    !mExcludedClasses.contains(getOuterClassName(class_name))) {
-                findClass(class_name, zipClasses, inOutFound);
-            }
-        }
-    }
-
-    Pattern getPatternFromGlob(String globPattern) {
-     // transforms the glob pattern in a regexp:
-        // - escape "." with "\."
-        // - replace "*" by "[^.]*"
-        // - escape "$" with "\$"
-        // - add end-of-line match $
-        globPattern = globPattern.replaceAll("\\$", "\\\\\\$");
-        globPattern = globPattern.replaceAll("\\.", "\\\\.");
-        // prevent ** from being altered by the next rule, then process the * rule and finally
-        // the real ** rule (which is now @)
-        globPattern = globPattern.replaceAll("\\*\\*", "@");
-        globPattern = globPattern.replaceAll("\\*", "[^.]*");
-        globPattern = globPattern.replaceAll("@", ".*");
-        globPattern += "$";
-
-        return Pattern.compile(globPattern);
-    }
-
-    /**
-     * Checks all the classes defined in the JarClassName instance and uses BCEL to
-     * determine if they are derived from the given FQCN super class name.
-     * Inserts the super class and all the class objects found in the map.
-     */
-    void findClassesDerivingFrom(String super_name, Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutFound) throws LogAbortException {
-        if (mExcludedClasses.contains(getOuterClassName(super_name))) {
-            return;
-        }
-        findClass(super_name, zipClasses, inOutFound);
-
-        for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-            String className = entry.getKey();
-            if (super_name.equals(className)) {
-                continue;
-            }
-            ClassReader classReader = entry.getValue();
-            ClassReader parent_cr = classReader;
-            while (parent_cr != null) {
-                String parent_name = internalToBinaryClassName(parent_cr.getSuperName());
-                if (parent_name == null) {
-                    // not found
-                    break;
-                } else if (super_name.equals(parent_name)) {
-                    inOutFound.put(className, classReader);
-                    break;
-                }
-                parent_cr = zipClasses.get(parent_name);
-            }
-        }
-    }
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    DependencyVisitor getVisitor(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inKeep,
-            Map<String, ClassReader> outKeep,
-            Map<String, ClassReader> inDeps,
-            Map<String, ClassReader> outDeps) {
-        return new DependencyVisitor(zipClasses, inKeep, outKeep, inDeps, outDeps);
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, ClassReader> findDeps(Map<String, ClassReader> zipClasses,
-            Map<String, ClassReader> inOutKeepClasses) {
-
-        TreeMap<String, ClassReader> deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> temp = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor(zipClasses,
-                inOutKeepClasses, new_keep,
-                deps, new_deps);
-
-        for (ClassReader cr : inOutKeepClasses.values()) {
-            visitor.setClassName(cr.getClassName());
-            cr.accept(visitor, 0 /* flags */);
-        }
-
-        while (new_deps.size() > 0 || new_keep.size() > 0) {
-            deps.putAll(new_deps);
-            inOutKeepClasses.putAll(new_keep);
-
-            temp.clear();
-            temp.putAll(new_deps);
-            temp.putAll(new_keep);
-            new_deps.clear();
-            new_keep.clear();
-            mLog.debug("Found %1$d to keep, %2$d dependencies.",
-                    inOutKeepClasses.size(), deps.size());
-
-            for (ClassReader cr : temp.values()) {
-                visitor.setClassName(cr.getClassName());
-                cr.accept(visitor, 0 /* flags */);
-            }
-        }
-
-        mLog.info("Found %1$d classes to keep, %2$d class dependencies.",
-                inOutKeepClasses.size(), deps.size());
-
-        return deps;
-    }
-
-    private String getOuterClassName(String className) {
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            return className.substring(0, pos);
-        }
-        return className;
-    }
-
-    // ----------------------------------
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        /** All classes found in the source JAR. */
-        private final Map<String, ClassReader> mZipClasses;
-        /** Classes from which dependencies are to be found. */
-        private final Map<String, ClassReader> mInKeep;
-        /** Dependencies already known. */
-        private final Map<String, ClassReader> mInDeps;
-        /** New dependencies found by this visitor. */
-        private final Map<String, ClassReader> mOutDeps;
-        /** New classes to keep as-is found by this visitor. */
-        private final Map<String, ClassReader> mOutKeep;
-
-        private String mClassName;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
-         * New dependencies are marked in outDeps.
-         *
-         * @param zipClasses All classes found in the source JAR.
-         * @param inKeep Classes from which dependencies are to be found.
-         * @param inDeps Dependencies already known.
-         * @param outDeps New dependencies found by this visitor.
-         */
-        public DependencyVisitor(Map<String, ClassReader> zipClasses,
-                Map<String, ClassReader> inKeep,
-                Map<String, ClassReader> outKeep,
-                Map<String,ClassReader> inDeps,
-                Map<String,ClassReader> outDeps) {
-            super(Main.ASM_VERSION);
-            mZipClasses = zipClasses;
-            mInKeep = inKeep;
-            mOutKeep = outKeep;
-            mInDeps = inDeps;
-            mOutDeps = outDeps;
-        }
-
-        private void setClassName(String className) {
-            mClassName = className;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         * If it does, add to the mOutDeps map.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            // exclude classes that have already been found or are marked to be excluded
-            if (mInKeep.containsKey(className) ||
-                    mOutKeep.containsKey(className) ||
-                    mInDeps.containsKey(className) ||
-                    mOutDeps.containsKey(className) ||
-                    mExcludedClasses.contains(getOuterClassName(className))) {
-                return;
-            }
-
-            // exclude classes that are not part of the JAR file being examined
-            ClassReader cr = mZipClasses.get(className);
-            if (cr == null) {
-                return;
-            }
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // accept this class:
-            // - android classes are added to dependencies
-            // - non-android classes are added to the list of classes to keep as-is (they don't need
-            //   to be stubbed).
-            if (className.contains("android")) {  // TODO make configurable
-                mOutDeps.put(className, cr);
-            } else {
-                mOutKeep.put(className, cr);
-            }
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public void considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    Type t = Type.getType(desc);
-                    considerType(t);
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-        }
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            considerName(name);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor(mClassName);
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            private String mOwnerClass;
-
-            public MyMethodVisitor(String ownerClass) {
-                super(Main.ASM_VERSION);
-                mOwnerClass = ownerClass;
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                considerName(owner);
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-
-
-                // Check if method needs to replaced by a call to a different method.
-                if (ReplaceMethodCallsAdapter.isReplacementNeeded(owner, name, desc, mOwnerClass)) {
-                    mReplaceMethodCallClasses.add(mOwnerClass);
-                }
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
deleted file mode 100644
index d59b419..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarOutputStream;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Class that generates a new JAR from a list of classes, some of which are to be kept as-is
- * and some of which are to be stubbed partially or totally.
- */
-public class AsmGenerator {
-
-    /** Output logger. */
-    private final Log mLog;
-    /** The path of the destination JAR to create. */
-    private final String mOsDestJar;
-    /** List of classes to inject in the final JAR from _this_ archive. */
-    private final Class<?>[] mInjectClasses;
-    /** All classes to output as-is, except if they have native methods. */
-    private Map<String, ClassReader> mKeep;
-    /** All dependencies that must be completely stubbed. */
-    private Map<String, ClassReader> mDeps;
-    /** All files that are to be copied as-is. */
-    private Map<String, InputStream> mCopyFiles;
-    /** All classes where certain method calls need to be rewritten. */
-    private Set<String> mReplaceMethodCallsClasses;
-    /** Counter of number of classes renamed during transform. */
-    private int mRenameCount;
-    /** FQCN Names of the classes to rename: map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRenameClasses;
-    /** FQCN Names of "old" classes that were NOT renamed. This starts with the full list of
-     *  old-FQCN to rename and they get erased as they get renamed. At the end, classes still
-     *  left here are not in the code base anymore and thus were not renamed. */
-    private HashSet<String> mClassesNotRenamed;
-    /** A map { FQCN => set { list of return types to delete from the FQCN } }. */
-    private HashMap<String, Set<String>> mDeleteReturns;
-    /** A map { FQCN => set { method names } } of methods to rewrite as delegates.
-     *  The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
-    private final HashMap<String, Set<String>> mDelegateMethods;
-    /** FQCN Names of classes to refactor. All reference to old-FQCN will be updated to new-FQCN.
-     * map old-FQCN => new-FQCN */
-    private final HashMap<String, String> mRefactorClasses;
-    /** Methods to inject. FQCN of class in which method should be injected => runnable that does
-     * the injection. */
-    private final Map<String, ICreateInfo.InjectMethodRunnable> mInjectedMethodsMap;
-    /** A map { FQCN => set { field names } } which should be promoted to public visibility */
-    private final Map<String, Set<String>> mPromotedFields;
-    /** A list of classes to be promoted to public visibility */
-    private final Set<String> mPromotedClasses;
-
-    /**
-     * Creates a new generator that can generate the output JAR with the stubbed classes.
-     *
-     * @param log Output logger.
-     * @param osDestJar The path of the destination JAR to create.
-     * @param createInfo Creation parameters. Must not be null.
-     */
-    public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
-        mLog = log;
-        mOsDestJar = osDestJar;
-        ArrayList<Class<?>> injectedClasses =
-                new ArrayList<>(Arrays.asList(createInfo.getInjectedClasses()));
-        // Search for and add anonymous inner classes also.
-        ListIterator<Class<?>> iter = injectedClasses.listIterator();
-        while (iter.hasNext()) {
-            Class<?> clazz = iter.next();
-            try {
-                int i = 1;
-                while(i < 100) {
-                    iter.add(Class.forName(clazz.getName() + "$" + i));
-                    i++;
-                }
-            } catch (ClassNotFoundException ignored) {
-                // Expected.
-            }
-        }
-        mInjectClasses = injectedClasses.toArray(new Class<?>[0]);
-
-        // Create the map/set of methods to change to delegates
-        mDelegateMethods = new HashMap<>();
-        addToMap(createInfo.getDelegateMethods(), mDelegateMethods);
-
-        for (String className : createInfo.getDelegateClassNatives()) {
-            className = binaryToInternalClassName(className);
-            Set<String> methods = mDelegateMethods.get(className);
-            if (methods == null) {
-                methods = new HashSet<>();
-                mDelegateMethods.put(className, methods);
-            }
-            methods.add(DelegateClassAdapter.ALL_NATIVES);
-        }
-
-        // Create the map of classes to rename.
-        mRenameClasses = new HashMap<>();
-        mClassesNotRenamed = new HashSet<>();
-        String[] renameClasses = Stream.concat(
-                Arrays.stream(createInfo.getRenamedClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        int n = renameClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            // The ASM class names uses "/" separators, whereas regular FQCN use "."
-            String oldFqcn = binaryToInternalClassName(renameClasses[i]);
-            String newFqcn = binaryToInternalClassName(renameClasses[i + 1]);
-            mRenameClasses.put(oldFqcn, newFqcn);
-            mClassesNotRenamed.add(oldFqcn);
-        }
-
-        // Create a map of classes to be refactored.
-        mRefactorClasses = new HashMap<>();
-        String[] refactorClasses = Stream.concat(
-                Arrays.stream(createInfo.getJavaPkgClasses()),
-                Arrays.stream(createInfo.getRefactoredClasses()))
-                .toArray(String[]::new);
-        n = refactorClasses.length;
-        for (int i = 0; i < n; i += 2) {
-            assert i + 1 < n;
-            String oldFqcn = binaryToInternalClassName(refactorClasses[i]);
-            String newFqcn = binaryToInternalClassName(refactorClasses[i + 1]);
-            mRefactorClasses.put(oldFqcn, newFqcn);
-        }
-
-        // create the map of renamed class -> return type of method to delete.
-        mDeleteReturns = new HashMap<>();
-        String[] deleteReturns = createInfo.getDeleteReturns();
-        Set<String> returnTypes = null;
-        String renamedClass = null;
-        for (String className : deleteReturns) {
-            // if we reach the end of a section, add it to the main map
-            if (className == null) {
-                if (returnTypes != null) {
-                    mDeleteReturns.put(renamedClass, returnTypes);
-                }
-
-                renamedClass = null;
-                continue;
-            }
-
-            // if the renamed class is null, this is the beginning of a section
-            if (renamedClass == null) {
-                renamedClass = binaryToInternalClassName(className);
-                continue;
-            }
-
-            // just a standard return type, we add it to the list.
-            if (returnTypes == null) {
-                returnTypes = new HashSet<>();
-            }
-            returnTypes.add(binaryToInternalClassName(className));
-        }
-
-        mPromotedFields = new HashMap<>();
-        addToMap(createInfo.getPromotedFields(), mPromotedFields);
-
-        mInjectedMethodsMap = createInfo.getInjectedMethodsMap();
-
-        mPromotedClasses =
-                Arrays.stream(createInfo.getPromotedClasses()).collect(Collectors.toSet());
-    }
-
-    /**
-     * For each value in the array, split the value on '#' and add the parts to the map as key
-     * and value.
-     */
-    private void addToMap(String[] entries, Map<String, Set<String>> map) {
-        for (String entry : entries) {
-            int pos = entry.indexOf('#');
-            if (pos <= 0 || pos >= entry.length() - 1) {
-                return;
-            }
-            String className = binaryToInternalClassName(entry.substring(0, pos));
-            String methodOrFieldName = entry.substring(pos + 1);
-            Set<String> set = map.get(className);
-            if (set == null) {
-                set = new HashSet<>();
-                map.put(className, set);
-            }
-            set.add(methodOrFieldName);
-        }
-    }
-
-    /**
-     * Returns the list of classes that have not been renamed yet.
-     * <p/>
-     * The names are "internal class names" rather than FQCN, i.e. they use "/" instead "."
-     * as package separators.
-     */
-    public Set<String> getClassesNotRenamed() {
-        return mClassesNotRenamed;
-    }
-
-    /**
-     * Utility that returns the internal ASM class name from a fully qualified binary class
-     * name. E.g. it returns android/view/View from android.view.View.
-     */
-    String binaryToInternalClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('.', '/');
-        }
-    }
-
-    /** Sets the map of classes to output as-is, except if they have native methods */
-    public void setKeep(Map<String, ClassReader> keep) {
-        mKeep = keep;
-    }
-
-    /** Sets the map of dependencies that must be completely stubbed */
-    public void setDeps(Map<String, ClassReader> deps) {
-        mDeps = deps;
-    }
-
-    /** Sets the map of files to output as-is. */
-    public void setCopyFiles(Map<String, InputStream> copyFiles) {
-        mCopyFiles = copyFiles;
-    }
-
-    public void setRewriteMethodCallClasses(Set<String> rewriteMethodCallClasses) {
-        mReplaceMethodCallsClasses = rewriteMethodCallClasses;
-    }
-
-    /** Generates the final JAR */
-    public void generate() throws IOException {
-        TreeMap<String, byte[]> all = new TreeMap<>();
-
-        for (Class<?> clazz : mInjectClasses) {
-            String name = classToEntryPath(clazz);
-            InputStream is = ClassLoader.getSystemResourceAsStream(name);
-            ClassReader cr = new ClassReader(is);
-            byte[] b = transform(cr, true);
-            name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, ClassReader> entry : mKeep.entrySet()) {
-            ClassReader cr = entry.getValue();
-            byte[] b = transform(cr, true);
-            String name = classNameToEntryPath(transformName(cr.getClassName()));
-            all.put(name, b);
-        }
-
-        for (Entry<String, InputStream> entry : mCopyFiles.entrySet()) {
-            try {
-                byte[] b = inputStreamToByteArray(entry.getValue());
-                all.put(entry.getKey(), b);
-            } catch (IOException e) {
-                // Ignore.
-            }
-
-        }
-        mLog.info("# deps classes: %d", mDeps.size());
-        mLog.info("# keep classes: %d", mKeep.size());
-        mLog.info("# renamed     : %d", mRenameCount);
-
-        createJar(new FileOutputStream(mOsDestJar), all);
-        mLog.info("Created JAR file %s", mOsDestJar);
-    }
-
-    /**
-     * Writes the JAR file.
-     *
-     * @param outStream The file output stream were to write the JAR.
-     * @param all The map of all classes to output.
-     * @throws IOException if an I/O error has occurred
-     */
-    void createJar(FileOutputStream outStream, Map<String,byte[]> all) throws IOException {
-        JarOutputStream jar = new JarOutputStream(outStream);
-        for (Entry<String, byte[]> entry : all.entrySet()) {
-            String name = entry.getKey();
-            JarEntry jar_entry = new JarEntry(name);
-            jar.putNextEntry(jar_entry);
-            jar.write(entry.getValue());
-            jar.closeEntry();
-        }
-        jar.flush();
-        jar.close();
-    }
-
-    /**
-     * Utility method that converts a fully qualified java name into a JAR entry path
-     * e.g. for the input "android.view.View" it returns "android/view/View.class"
-     */
-    String classNameToEntryPath(String className) {
-        return className.replace('.', '/').concat(".class");
-    }
-
-    /**
-     * Utility method to get the JAR entry path from a Class name.
-     * e.g. it returns something like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
-     */
-    private String classToEntryPath(Class<?> clazz) {
-        return classNameToEntryPath(clazz.getName());
-    }
-
-    /**
-     * Transforms a class.
-     * <p/>
-     * There are 3 kind of transformations:
-     *
-     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
-     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
-     * left intact. Modified classes must be overridable (non-private, non-final).
-     * Native methods must be made non-final, non-private.
-     *
-     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
-     * If a class has native methods, it must also be made non-private, non-final.
-     *
-     * Note that unfortunately static methods cannot be changed to non-static (since static and
-     * non-static are invoked differently.)
-     */
-    byte[] transform(ClassReader cr, boolean stubNativesOnly) {
-
-        boolean hasNativeMethods = hasNativeMethods(cr);
-
-        // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
-        String className = cr.getClassName();
-
-        String newName = transformName(className);
-        // transformName returns its input argument if there's no need to rename the class
-        if (!newName.equals(className)) {
-            mRenameCount++;
-            // This class is being renamed, so remove it from the list of classes not renamed.
-            mClassesNotRenamed.remove(className);
-        }
-
-        mLog.debug("Transform %s%s%s%s", className,
-                newName.equals(className) ? "" : " (renamed to " + newName + ")",
-                hasNativeMethods ? " -- has natives" : "",
-                stubNativesOnly ? " -- stub natives only" : "");
-
-        // Rewrite the new class from scratch, without reusing the constant pool from the
-        // original class reader.
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-        ClassVisitor cv = cw;
-
-        // FIXME Generify
-        if ("android/content/res/Resources".equals(className)) {
-            cv = new FieldInjectorAdapter(cv);
-        }
-        if (mReplaceMethodCallsClasses.contains(className)) {
-            cv = new ReplaceMethodCallsAdapter(cv, className);
-        }
-
-        cv = new RefactorClassAdapter(cv, mRefactorClasses);
-        if (!newName.equals(className)) {
-            cv = new RenameClassAdapter(cv, className, newName);
-        }
-
-        String binaryNewName = newName.replace('/', '.');
-        if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
-            cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
-        }
-        cv = new TransformClassAdapter(mLog, Collections.emptySet(), mDeleteReturns.get(className),
-                newName, cv, stubNativesOnly);
-
-        Set<String> delegateMethods = mDelegateMethods.get(className);
-        if (delegateMethods != null && !delegateMethods.isEmpty()) {
-            // If delegateMethods only contains one entry ALL_NATIVES and the class is
-            // known to have no native methods, just skip this step.
-            if (hasNativeMethods ||
-                    !(delegateMethods.size() == 1 &&
-                            delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
-                cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
-            }
-        }
-
-        Set<String> promoteFields = mPromotedFields.get(className);
-        if (promoteFields != null && !promoteFields.isEmpty()) {
-            cv = new PromoteFieldClassAdapter(cv, promoteFields);
-        }
-        if (!mPromotedClasses.isEmpty()) {
-            cv = new PromoteClassClassAdapter(cv, mPromotedClasses);
-        }
-        cr.accept(cv, 0);
-
-        return cw.toByteArray();
-    }
-
-    /**
-     * Should this class be renamed, this returns the new name. Otherwise it returns the
-     * original name.
-     *
-     * @param className The internal ASM name of the class that may have to be renamed
-     * @return A new transformed name or the original input argument.
-     */
-    String transformName(String className) {
-        String newName = mRenameClasses.get(className);
-        if (newName != null) {
-            return newName;
-        }
-        int pos = className.indexOf('$');
-        if (pos > 0) {
-            // Is this an inner class of a renamed class?
-            String base = className.substring(0, pos);
-            newName = mRenameClasses.get(base);
-            if (newName != null) {
-                return newName + className.substring(pos);
-            }
-        }
-
-        return className;
-    }
-
-    /**
-     * Returns true if a class has any native methods.
-     */
-    boolean hasNativeMethods(ClassReader cr) {
-        ClassHasNativeVisitor cv = new ClassHasNativeVisitor();
-        cr.accept(cv, 0);
-        return cv.hasNativeMethods();
-    }
-
-    private byte[] inputStreamToByteArray(InputStream is) throws IOException {
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        byte[] data = new byte[8192];  // 8KB
-        int n;
-        while ((n = is.read(data, 0, data.length)) != -1) {
-            buffer.write(data, 0, n);
-        }
-        return buffer.toByteArray();
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
deleted file mode 100644
index 4748a7c..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Indicates if a class contains any native methods.
- */
-public class ClassHasNativeVisitor extends ClassVisitor {
-    public ClassHasNativeVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    private boolean mHasNativeMethods = false;
-
-    public boolean hasNativeMethods() {
-        return mHasNativeMethods;
-    }
-
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-        mHasNativeMethods = hasNativeMethods;
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        // pass
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitAttribute(Attribute attr) {
-        // pass
-    }
-
-    @Override
-    public void visitEnd() {
-        // pass
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        // pass
-        return null;
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName,
-            String innerName, int access) {
-        // pass
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        if ((access & Opcodes.ACC_NATIVE) != 0) {
-            setHasNativeMethods(true, name);
-        }
-        return null;
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        // pass
-    }
-
-    @Override
-    public void visitSource(String source, String debug) {
-        // pass
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
deleted file mode 100644
index cb0bc6d..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.AutoCloseable;
-import com.android.tools.layoutlib.java.Charsets;
-import com.android.tools.layoutlib.java.IntegralToString;
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.Objects;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.tools.layoutlib.java.UnsafeByteSequence;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Describes the work to be done by {@link AsmGenerator}.
- */
-public final class CreateInfo implements ICreateInfo {
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return INJECTED_CLASSES;
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return DELEGATE_METHODS;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return DELEGATE_CLASS_NATIVES;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return RENAMED_CLASSES;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return DELETE_RETURNS;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-      return JAVA_PKG_CLASSES;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return REFACTOR_CLASSES;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        String[] refactoredClasses = getJavaPkgClasses();
-        int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length;
-        Set<String> excludedClasses = new HashSet<>(count);
-        for (int i = 0; i < refactoredClasses.length; i+=2) {
-            excludedClasses.add(refactoredClasses[i]);
-        }
-        excludedClasses.addAll(Arrays.asList(EXCLUDED_CLASSES));
-        return excludedClasses;
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return PROMOTED_FIELDS;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return PROMOTED_CLASSES;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return INJECTED_METHODS;
-    }
-
-    //-----
-
-    /**
-     * The list of class from layoutlib_create to inject in layoutlib.
-     */
-    private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
-            OverrideMethod.class,
-            MethodListener.class,
-            MethodAdapter.class,
-            ICreateInfo.class,
-            CreateInfo.class,
-            LayoutlibDelegate.class,
-            InjectMethodRunnable.class,
-            InjectMethodRunnables.class,
-            /* Java package classes */
-            IntegralToString.class,
-            UnsafeByteSequence.class,
-            System_Delegate.class,
-            LinkedHashMap_Delegate.class,
-        };
-
-    /**
-     * The list of methods to rewrite as delegates.
-     */
-    public final static String[] DELEGATE_METHODS = new String[] {
-        "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
-        "android.content.res.Resources#getAnimation",
-        "android.content.res.Resources#getBoolean",
-        "android.content.res.Resources#getColor",
-        "android.content.res.Resources#getColorStateList",
-        "android.content.res.Resources#getDimension",
-        "android.content.res.Resources#getDimensionPixelOffset",
-        "android.content.res.Resources#getDimensionPixelSize",
-        "android.content.res.Resources#getDrawable",
-        "android.content.res.Resources#getFont",
-        "android.content.res.Resources#getIntArray",
-        "android.content.res.Resources#getInteger",
-        "android.content.res.Resources#getLayout",
-        "android.content.res.Resources#getQuantityString",
-        "android.content.res.Resources#getQuantityText",
-        "android.content.res.Resources#getResourceEntryName",
-        "android.content.res.Resources#getResourceName",
-        "android.content.res.Resources#getResourcePackageName",
-        "android.content.res.Resources#getResourceTypeName",
-        "android.content.res.Resources#getString",
-        "android.content.res.Resources#getStringArray",
-        "android.content.res.Resources#getText",
-        "android.content.res.Resources#getTextArray",
-        "android.content.res.Resources#getValue",
-        "android.content.res.Resources#getXml",
-        "android.content.res.Resources#loadXmlResourceParser",
-        "android.content.res.Resources#obtainAttributes",
-        "android.content.res.Resources#obtainTypedArray",
-        "android.content.res.Resources#openRawResource",
-        "android.content.res.Resources#openRawResourceFd",
-        "android.content.res.Resources$Theme#obtainStyledAttributes",
-        "android.content.res.Resources$Theme#resolveAttribute",
-        "android.content.res.Resources$Theme#resolveAttributes",
-        "android.content.res.AssetManager#newTheme",
-        "android.content.res.AssetManager#deleteTheme",
-        "android.content.res.AssetManager#getAssignedPackageIdentifiers",
-        "android.content.res.TypedArray#getValueAt",
-        "android.content.res.TypedArray#obtain",
-        "android.graphics.BitmapFactory#finishDecode",
-        "android.graphics.BitmapFactory#setDensityFromOptions",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget",
-        "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#onDraw",
-        "android.graphics.drawable.GradientDrawable#buildRing",
-        "android.graphics.FontFamily#addFont",
-        "android.graphics.Typeface#getSystemFontConfigLocation",
-        "android.graphics.Typeface#makeFamilyFromParsed",
-        "android.os.Handler#sendMessageAtTime",
-        "android.os.HandlerThread#run",
-        "android.preference.Preference#getView",
-        "android.text.format.DateFormat#is24HourFormat",
-        "android.text.Hyphenator#getSystemHyphenatorLocation",
-        "android.util.Xml#newPullParser",
-        "android.view.Choreographer#getInstance",
-        "android.view.Choreographer#getRefreshRate",
-        "android.view.Choreographer#scheduleVsyncLocked",
-        "android.view.Display#updateDisplayInfoLocked",
-        "android.view.Display#getWindowManager",
-        "android.view.HandlerActionQueue#postDelayed",
-        "android.view.LayoutInflater#rInflate",
-        "android.view.LayoutInflater#parseInclude",
-        "android.view.View#getWindowToken",
-        "android.view.View#isInEditMode",
-        "android.view.ViewRootImpl#isInTouchMode",
-        "android.view.WindowManagerGlobal#getWindowManagerService",
-        "android.view.inputmethod.InputMethodManager#getInstance",
-        "android.view.MenuInflater#registerMenu",
-        "android.view.RenderNode#getMatrix",
-        "android.view.RenderNode#nCreate",
-        "android.view.RenderNode#nGetNativeFinalizer",
-        "android.view.RenderNode#nSetElevation",
-        "android.view.RenderNode#nGetElevation",
-        "android.view.RenderNode#nSetTranslationX",
-        "android.view.RenderNode#nGetTranslationX",
-        "android.view.RenderNode#nSetTranslationY",
-        "android.view.RenderNode#nGetTranslationY",
-        "android.view.RenderNode#nSetTranslationZ",
-        "android.view.RenderNode#nGetTranslationZ",
-        "android.view.RenderNode#nSetRotation",
-        "android.view.RenderNode#nGetRotation",
-        "android.view.RenderNode#nSetLeft",
-        "android.view.RenderNode#nSetTop",
-        "android.view.RenderNode#nSetRight",
-        "android.view.RenderNode#nSetBottom",
-        "android.view.RenderNode#nSetLeftTopRightBottom",
-        "android.view.RenderNode#nSetPivotX",
-        "android.view.RenderNode#nGetPivotX",
-        "android.view.RenderNode#nSetPivotY",
-        "android.view.RenderNode#nGetPivotY",
-        "android.view.RenderNode#nSetScaleX",
-        "android.view.RenderNode#nGetScaleX",
-        "android.view.RenderNode#nSetScaleY",
-        "android.view.RenderNode#nGetScaleY",
-        "android.view.RenderNode#nIsPivotExplicitlySet",
-        "android.view.PointerIcon#loadResource",
-        "android.view.ViewGroup#drawChild",
-        "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
-        "com.android.internal.util.XmlUtils#convertValueToInt",
-        "dalvik.system.VMRuntime#newUnpaddedArray",
-        "libcore.io.MemoryMappedFile#mmapRO",
-        "libcore.io.MemoryMappedFile#close",
-        "libcore.io.MemoryMappedFile#bigEndianIterator",
-        "libcore.util.NativeAllocationRegistry#applyFreeFunction",
-    };
-
-    /**
-     * The list of classes on which to delegate all native methods.
-     */
-    public final static String[] DELEGATE_CLASS_NATIVES = new String[] {
-        "android.animation.PropertyValuesHolder",
-        "android.graphics.BaseCanvas",
-        "android.graphics.Bitmap",
-        "android.graphics.BitmapFactory",
-        "android.graphics.BitmapShader",
-        "android.graphics.BlurMaskFilter",
-        "android.graphics.Canvas",
-        "android.graphics.ColorFilter",
-        "android.graphics.ColorMatrixColorFilter",
-        "android.graphics.ComposePathEffect",
-        "android.graphics.ComposeShader",
-        "android.graphics.CornerPathEffect",
-        "android.graphics.DashPathEffect",
-        "android.graphics.DiscretePathEffect",
-        "android.graphics.DrawFilter",
-        "android.graphics.EmbossMaskFilter",
-        "android.graphics.FontFamily",
-        "android.graphics.LightingColorFilter",
-        "android.graphics.LinearGradient",
-        "android.graphics.MaskFilter",
-        "android.graphics.Matrix",
-        "android.graphics.NinePatch",
-        "android.graphics.Paint",
-        "android.graphics.PaintFlagsDrawFilter",
-        "android.graphics.Path",
-        "android.graphics.PathDashPathEffect",
-        "android.graphics.PathEffect",
-        "android.graphics.PathMeasure",
-        "android.graphics.PorterDuffColorFilter",
-        "android.graphics.RadialGradient",
-        "android.graphics.Region",
-        "android.graphics.Shader",
-        "android.graphics.SumPathEffect",
-        "android.graphics.SweepGradient",
-        "android.graphics.Typeface",
-        "android.graphics.drawable.AnimatedVectorDrawable",
-        "android.graphics.drawable.VectorDrawable",
-        "android.os.SystemClock",
-        "android.os.SystemProperties",
-        "android.text.AndroidBidi",
-        "android.text.StaticLayout",
-        "android.util.PathParser",
-        "android.view.Display",
-        "com.android.internal.util.VirtualRefBasePtr",
-        "com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
-        "libcore.icu.ICU",
-    };
-
-    /**
-     *  The list of classes to rename, must be an even list: the binary FQCN
-     *  of class to replace followed by the new FQCN.
-     */
-    private final static String[] RENAMED_CLASSES =
-        new String[] {
-            "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
-            "android.view.textservice.TextServicesManager",    "android.view.textservice._Original_TextServicesManager",
-            "android.util.LruCache",                           "android.util._Original_LruCache",
-            "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
-            "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
-            "android.webkit.WebView",                          "android.webkit._Original_WebView",
-        };
-
-    /**
-     * The list of class references to update, must be an even list: the binary
-     * FQCN of class to replace followed by the new FQCN. The classes to
-     * replace are to be excluded from the output.
-     */
-    private final static String[] JAVA_PKG_CLASSES =
-        new String[] {
-            "java.nio.charset.Charsets",                       "java.nio.charset.StandardCharsets",
-            "java.lang.IntegralToString",                      "com.android.tools.layoutlib.java.IntegralToString",
-            "java.lang.UnsafeByteSequence",                    "com.android.tools.layoutlib.java.UnsafeByteSequence",
-            // Use android.icu.text versions of DateFormat and SimpleDateFormat since the
-            // original ones do not match the Android implementation
-            "java.text.DateFormat",                            "android.icu.text.DateFormat",
-            "java.text.SimpleDateFormat",                      "android.icu.text.SimpleDateFormat",
-        };
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    private final static String[] REFACTOR_CLASSES =
-            new String[] {
-                    "android.os.Build",                                "android.os._Original_Build",
-            };
-
-    private final static String[] EXCLUDED_CLASSES =
-        new String[] {
-            "android.preference.PreferenceActivity",
-            "org.kxml2.io.KXmlParser",
-        };
-
-    /**
-     * List of fields for which we will update the visibility to be public. This is sometimes
-     * needed when access from the delegate classes is needed.
-     */
-    private final static String[] PROMOTED_FIELDS = new String[] {
-        "android.graphics.drawable.VectorDrawable#mVectorState",
-        "android.view.Choreographer#mLastFrameTimeNanos",
-        "android.graphics.FontFamily#mBuilderPtr",
-        "android.graphics.Typeface#sDynamicTypefaceCache"
-    };
-
-    /**
-     * List of classes to be promoted to public visibility. Prefer using PROMOTED_FIELDS to this
-     * if possible.
-     */
-    private final static String[] PROMOTED_CLASSES = new String[] {
-    };
-
-    /**
-     * List of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     */
-    private final static String[] DELETE_RETURNS =
-        new String[] {
-            null };                         // separator, for next class/methods list.
-
-    private final static Map<String, InjectMethodRunnable> INJECTED_METHODS =
-            new HashMap<String, InjectMethodRunnable>(1) {{
-                put("android.content.Context",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }};
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
deleted file mode 100644
index cbb3a8ab..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.util.Set;
-
-/**
- * A {@link DelegateClassAdapter} can transform some methods from a class into
- * delegates that defer the call to an associated delegate class.
- * <p/>
- * This is used to override specific methods and or all native methods in classes.
- */
-public class DelegateClassAdapter extends ClassVisitor {
-
-    /** Suffix added to original methods. */
-    private static final String ORIGINAL_SUFFIX = "_Original";
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    public static final String ALL_NATIVES = "<<all_natives>>";
-
-    private final String mClassName;
-    private final Set<String> mDelegateMethods;
-    private final Log mLog;
-    private boolean mIsStaticInnerClass;
-
-    /**
-     * Creates a new {@link DelegateClassAdapter} that can transform some methods
-     * from a class into delegates that defer the call to an associated delegate class.
-     * <p/>
-     * This is used to override specific methods and or all native methods in classes.
-     *
-     * @param log The logger object. Must not be null.
-     * @param cv the class visitor to which this adapter must delegate calls.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param delegateMethods The set of method names to modify and/or the
-     *          special constant {@link #ALL_NATIVES} to convert all native methods.
-     */
-    public DelegateClassAdapter(Log log,
-            ClassVisitor cv,
-            String className,
-            Set<String> delegateMethods) {
-        super(Main.ASM_VERSION, cv);
-        mLog = log;
-        mClassName = className;
-        mDelegateMethods = delegateMethods;
-        // If this is an inner class, by default, we assume it's static. If it's not we will detect
-        // by looking at the fields (see visitField)
-        mIsStaticInnerClass = className.contains("$");
-    }
-
-    //----------------------------------
-    // Methods from the ClassAdapter
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mIsStaticInnerClass && "this$0".equals(name)) {
-            // Having a "this$0" field, proves that this class is not a static inner class.
-            mIsStaticInnerClass = false;
-        }
-
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        boolean isStaticMethod = (access & Opcodes.ACC_STATIC) != 0;
-        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-        boolean useDelegate = (isNative && mDelegateMethods.contains(ALL_NATIVES)) ||
-                              mDelegateMethods.contains(name);
-
-        if (!useDelegate) {
-            // Not creating a delegate for this method, pass it as-is from the reader to the writer.
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-
-        if (CONSTRUCTOR.equals(name) || CLASS_INIT.equals(name)) {
-            // We don't currently support generating delegates for constructors.
-            throw new UnsupportedOperationException(
-                String.format(
-                    "Delegate doesn't support overriding constructor %1$s:%2$s(%3$s)",  //$NON-NLS-1$
-                    mClassName, name, desc));
-        }
-
-        if (isNative) {
-            // Remove native flag
-            access = access & ~Opcodes.ACC_NATIVE;
-            MethodVisitor mwDelegate = super.visitMethod(access, name, desc, signature, exceptions);
-
-            DelegateMethodAdapter a = new DelegateMethodAdapter(
-                    mLog, null, mwDelegate, mClassName, name, desc, isStaticMethod,
-                    mIsStaticInnerClass);
-
-            // A native has no code to visit, so we need to generate it directly.
-            a.generateDelegateCode();
-
-            return mwDelegate;
-        }
-
-        // Given a non-native SomeClass.MethodName(), we want to generate 2 methods:
-        // - A copy of the original method named SomeClass.MethodName_Original().
-        //   The content is the original method as-is from the reader.
-        // - A brand new implementation of SomeClass.MethodName() which calls to a
-        //   non-existing method named SomeClass_Delegate.MethodName().
-        //   The implementation of this 'delegate' method is done in layoutlib_bridge.
-
-        int accessDelegate = access;
-        access = access & ~Opcodes.ACC_PRIVATE;  // If private, make it package protected.
-
-        MethodVisitor mwOriginal = super.visitMethod(access, name + ORIGINAL_SUFFIX,
-                                                     desc, signature, exceptions);
-        MethodVisitor mwDelegate = super.visitMethod(accessDelegate, name,
-                                                     desc, signature, exceptions);
-
-        return new DelegateMethodAdapter(
-                mLog, mwOriginal, mwDelegate, mClassName, name, desc, isStaticMethod,
-                mIsStaticInnerClass);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
deleted file mode 100644
index da8babc..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-
-/**
- * This method adapter generates delegate methods.
- * <p/>
- * Given a method {@code SomeClass.MethodName()}, this generates 1 or 2 methods:
- * <ul>
- * <li> A copy of the original method named {@code SomeClass.MethodName_Original()}.
- *   The content is the original method as-is from the reader.
- *   This step is omitted if the method is native, since it has no Java implementation.
- * <li> A brand new implementation of {@code SomeClass.MethodName()} which calls to a
- *   non-existing method named {@code SomeClass_Delegate.MethodName()}.
- *   The implementation of this 'delegate' method is done in layoutlib_brigde.
- * </ul>
- * A method visitor is generally constructed to generate a single method; however
- * here we might want to generate one or two depending on the context. To achieve
- * that, the visitor here generates the 'original' method and acts as a no-op if
- * no such method exists (e.g. when the original is a native method).
- * The delegate method is generated after the {@code visitEnd} of the original method
- * or by having the class adapter <em>directly</em> call {@link #generateDelegateCode()}
- * for native methods.
- * <p/>
- * When generating the 'delegate', the implementation generates a call to a class
- * class named <code>&lt;className&gt;_Delegate</code> with static methods matching
- * the methods to be overridden here. The methods have the same return type.
- * The argument type list is the same except the "this" reference is passed first
- * for non-static methods.
- * <p/>
- * A new annotation is added to these 'delegate' methods so that we can easily find them
- * for automated testing.
- * <p/>
- * This class isn't intended to be generic or reusable.
- * It is called by {@link DelegateClassAdapter}, which takes care of properly initializing
- * the two method writers for the original and the delegate class, as needed, with their
- * expected names.
- * <p/>
- * The class adapter also takes care of calling {@link #generateDelegateCode()} directly for
- * a native and use the visitor pattern for non-natives.
- * Note that native methods have, by definition, no code so there's nothing a visitor
- * can visit.
- * <p/>
- * Instances of this class are not re-usable.
- * The class adapter creates a new instance for each method.
- */
-class DelegateMethodAdapter extends MethodVisitor {
-
-    /** Suffix added to delegate classes. */
-    public static final String DELEGATE_SUFFIX = "_Delegate";
-
-    /** The parent method writer to copy of the original method.
-     *  Null when dealing with a native original method. */
-    private MethodVisitor mOrgWriter;
-    /** The parent method writer to generate the delegating method. Never null. */
-    private MethodVisitor mDelWriter;
-    /** The original method descriptor (return type + argument types.) */
-    private String mDesc;
-    /** True if the original method is static. */
-    private final boolean mIsStatic;
-    /** True if the method is contained in a static inner class */
-    private final boolean mIsStaticInnerClass;
-    /** The internal class name (e.g. <code>com/android/SomeClass$InnerClass</code>.) */
-    private final String mClassName;
-    /** The method name. */
-    private final String mMethodName;
-    /** Logger object. */
-    private final Log mLog;
-
-    /** Array used to capture the first line number information from the original method
-     *  and duplicate it in the delegate. */
-    private Object[] mDelegateLineNumber;
-
-    /**
-     * Creates a new {@link DelegateMethodAdapter} that will transform this method
-     * into a delegate call.
-     * <p/>
-     * See {@link DelegateMethodAdapter} for more details.
-     *
-     * @param log The logger object. Must not be null.
-     * @param mvOriginal The parent method writer to copy of the original method.
-     *          Must be {@code null} when dealing with a native original method.
-     * @param mvDelegate The parent method writer to generate the delegating method.
-     *          Must never be null.
-     * @param className The internal class name of the class to visit,
-     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
-     * @param methodName The simple name of the method.
-     * @param desc A method descriptor (c.f. {@link Type#getReturnType(String)} +
-     *          {@link Type#getArgumentTypes(String)})
-     * @param isStatic True if the method is declared static.
-     */
-    public DelegateMethodAdapter(Log log,
-            MethodVisitor mvOriginal,
-            MethodVisitor mvDelegate,
-            String className,
-            String methodName,
-            String desc,
-            boolean isStatic,
-            boolean isStaticClass) {
-        super(Main.ASM_VERSION);
-        mLog = log;
-        mOrgWriter = mvOriginal;
-        mDelWriter = mvDelegate;
-        mClassName = className;
-        mMethodName = methodName;
-        mDesc = desc;
-        mIsStatic = isStatic;
-        mIsStaticInnerClass = isStaticClass;
-    }
-
-    /**
-     * Generates the new code for the method.
-     * <p/>
-     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
-     * (since they have no code to visit).
-     * <p/>
-     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
-     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
-     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
-     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
-     */
-    public void generateDelegateCode() {
-        /*
-         * The goal is to generate a call to a static delegate method.
-         * If this method is non-static, the first parameter will be 'this'.
-         * All the parameters must be passed and then the eventual return type returned.
-         *
-         * Example, let's say we have a method such as
-         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
-         *
-         * We'll want to create a body that calls a delegate method like this:
-         *   TheClass_Delegate.myMethod(this, a, b, c);
-         *
-         * If the method is non-static and the class name is an inner class (e.g. has $ in its
-         * last segment), we want to push the 'this' of the outer class first:
-         *   OuterClass_InnerClass_Delegate.myMethod(
-         *     OuterClass.this,
-         *     OuterClass$InnerClass.this,
-         *     a, b, c);
-         *
-         * Only one level of inner class is supported right now, for simplicity and because
-         * we don't need more.
-         *
-         * The generated class name is the current class name with "_Delegate" appended to it.
-         * One thing to realize is that we don't care about generics -- since generic types
-         * are erased at build time, they have no influence on the method name being called.
-         */
-
-        // Add our annotation
-        AnnotationVisitor aw = mDelWriter.visitAnnotation(
-                Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(),
-                true); // visible at runtime
-        if (aw != null) {
-            aw.visitEnd();
-        }
-
-        mDelWriter.visitCode();
-
-        if (mDelegateLineNumber != null) {
-            Object[] p = mDelegateLineNumber;
-            mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
-        }
-
-        ArrayList<Type> paramTypes = new ArrayList<>();
-        String delegateClassName = mClassName + DELEGATE_SUFFIX;
-        boolean pushedArg0 = false;
-        int maxStack = 0;
-
-        // Check if the last segment of the class name has inner an class.
-        // Right now we only support one level of inner classes.
-        Type outerType = null;
-        int slash = mClassName.lastIndexOf('/');
-        int dol = mClassName.lastIndexOf('$');
-        if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
-            String outerClass = mClassName.substring(0, dol);
-            outerType = Type.getObjectType(outerClass);
-
-            // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
-            delegateClassName = delegateClassName.replace('$', '_');
-        }
-
-        // For an instance method (e.g. non-static), push the 'this' preceded
-        // by the 'this' of any outer class, if any.
-        if (!mIsStatic) {
-
-            if (outerType != null && !mIsStaticInnerClass) {
-                // The first-level inner class has a package-protected member called 'this$0'
-                // that points to the outer class.
-
-                // Push this.getField("this$0") on the call stack.
-                mDelWriter.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
-                mDelWriter.visitFieldInsn(Opcodes.GETFIELD,
-                        mClassName,                 // class where the field is defined
-                        "this$0",                   // field name
-                        outerType.getDescriptor()); // type of the field
-                maxStack++;
-                paramTypes.add(outerType);
-
-            }
-
-            // Push "this" for the instance method, which is always ALOAD 0
-            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
-            maxStack++;
-            pushedArg0 = true;
-            paramTypes.add(Type.getObjectType(mClassName));
-        }
-
-        // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
-        Type[] argTypes = Type.getArgumentTypes(mDesc);
-        int maxLocals = pushedArg0 ? 1 : 0;
-        for (Type t : argTypes) {
-            int size = t.getSize();
-            mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
-            maxLocals += size;
-            maxStack += size;
-            paramTypes.add(t);
-        }
-
-        // Construct the descriptor of the delegate based on the parameters
-        // we pushed on the call stack. The return type remains unchanged.
-        String desc = Type.getMethodDescriptor(
-                Type.getReturnType(mDesc),
-                paramTypes.toArray(new Type[paramTypes.size()]));
-
-        // Invoke the static delegate
-        mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC,
-                delegateClassName,
-                mMethodName,
-                desc,
-                false);
-
-        Type returnType = Type.getReturnType(mDesc);
-        mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
-
-        mDelWriter.visitMaxs(maxStack, maxLocals);
-        mDelWriter.visitEnd();
-
-        // For debugging now. Maybe we should collect these and store them in
-        // a text file for helping create the delegates. We could also compare
-        // the text file to a golden and break the build on unsupported changes
-        // or regressions. Even better we could fancy-print something that looks
-        // like the expected Java method declaration.
-        mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitCode();
-        }
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMaxs(maxStack, maxLocals);
-        }
-    }
-
-    /** End of visiting. Generate the delegating code. */
-    @Override
-    public void visitEnd() {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitEnd();
-        }
-        generateDelegateCode();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotation(desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitAnnotationDefault();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        if (mOrgWriter != null) {
-            return mOrgWriter.visitParameterAnnotation(parameter, desc, visible);
-        } else {
-            return null;
-        }
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitAttribute(attr);
-        }
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        // Capture the first line values for the new delegate method
-        if (mDelegateLineNumber == null) {
-            mDelegateLineNumber = new Object[] { line, start };
-        }
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLineNumber(line, start);
-        }
-    }
-
-    @Override
-    public void visitInsn(int opcode) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitInsn(opcode);
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mOrgWriter != null) {
-            mOrgWriter.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
deleted file mode 100644
index aa68ea0..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DependencyFinder.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.signature.SignatureReader;
-import org.objectweb.asm.signature.SignatureVisitor;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Analyzes the input JAR using the ASM java bytecode manipulation library
- * to list the classes and their dependencies. A "dependency" is a class
- * used by another class.
- */
-public class DependencyFinder {
-
-    // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-
-    /** Output logger. */
-    private final Log mLog;
-
-    /**
-     * Creates a new analyzer.
-     *
-     * @param log The log output.
-     */
-    public DependencyFinder(Log log) {
-        mLog = log;
-    }
-
-    /**
-     * Starts the analysis using parameters from the constructor.
-     *
-     * @param osJarPath The input source JARs to parse.
-     * @return A pair: [0]: map { class FQCN => set of FQCN class dependencies }.
-     *                 [1]: map { missing class FQCN => set of FQCN class that uses it. }
-     */
-    public List<Map<String, Set<String>>> findDeps(List<String> osJarPath) throws IOException {
-
-        Map<String, ClassReader> zipClasses = parseZip(osJarPath);
-        mLog.info("Found %d classes in input JAR%s.",
-                zipClasses.size(),
-                osJarPath.size() > 1 ? "s" : "");
-
-        Map<String, Set<String>> deps = findClassesDeps(zipClasses);
-
-        Map<String, Set<String>> missing = findMissingClasses(deps, zipClasses.keySet());
-
-        List<Map<String, Set<String>>> result = new ArrayList<>(2);
-        result.add(deps);
-        result.add(missing);
-        return result;
-    }
-
-    /**
-     * Prints dependencies to the current logger, found stuff and missing stuff.
-     */
-    public void printAllDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        // Print all dependences found in the format:
-        // +Found: <FQCN from zip>
-        //     uses: FQCN
-
-        mLog.info("++++++ %d Entries found in source JARs", deps.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            mLog.info(    "+Found  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("    uses: %s", dep);
-            }
-
-            mLog.info("");
-        }
-
-
-        // Now print all missing dependences in the format:
-        // -Missing <FQCN>:
-        //     used by: <FQCN>
-
-        mLog.info("");
-        mLog.info("------ %d Entries missing from source JARs", missing.size());
-        mLog.info("");
-
-        for (Entry<String, Set<String>> entry : missing.entrySet()) {
-            mLog.info(    "-Missing  : %s", entry.getKey());
-            for (String dep : entry.getValue()) {
-                mLog.info("   used by: %s", dep);
-            }
-
-            mLog.info("");
-        }
-    }
-
-    /**
-     * Prints only a summary of the missing dependencies to the current logger.
-     */
-    public void printMissingDeps(List<Map<String, Set<String>>> result) {
-        assert result.size() == 2;
-        @SuppressWarnings("unused") Map<String, Set<String>> deps = result.get(0);
-        Map<String, Set<String>> missing = result.get(1);
-
-        for (String fqcn : missing.keySet()) {
-            mLog.info("%s", fqcn);
-        }
-    }
-
-    // ----------------
-
-    /**
-     * Parses a JAR file and returns a list of all classes founds using a map
-     * class name => ASM ClassReader. Class names are in the form "android.view.View".
-     */
-    Map<String,ClassReader> parseZip(List<String> jarPathList) throws IOException {
-        TreeMap<String, ClassReader> classes = new TreeMap<>();
-
-        for (String jarPath : jarPathList) {
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                }
-            }
-        }
-
-        return classes;
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name for a ClassReader.
-     * E.g. it returns something like android.view.View.
-     */
-    static String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * Utility that returns the fully qualified binary class name from a path-like FQCN.
-     * E.g. it returns android.view.View from android/view/View.
-     */
-    static String internalToBinaryClassName(String className) {
-        if (className == null) {
-            return null;
-        } else {
-            return className.replace('/', '.');
-        }
-    }
-
-    /**
-     * Finds all dependencies for all classes in keepClasses which are also
-     * listed in zipClasses. Returns a map of all the dependencies found.
-     */
-    Map<String, Set<String>> findClassesDeps(Map<String, ClassReader> zipClasses) {
-
-        // The dependencies that we'll collect.
-        // It's a map Class name => uses class names.
-        Map<String, Set<String>> dependencyMap = new TreeMap<>();
-
-        DependencyVisitor visitor = getVisitor();
-
-        int count = 0;
-        try {
-            for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
-                String name = entry.getKey();
-
-                TreeSet<String> set = new TreeSet<>();
-                dependencyMap.put(name, set);
-                visitor.setDependencySet(set);
-
-                ClassReader cr = entry.getValue();
-                cr.accept(visitor, 0 /* flags */);
-
-                visitor.setDependencySet(null);
-
-                mLog.debugNoln("Visited %d classes\r", ++count);
-            }
-        } finally {
-            mLog.debugNoln("\n");
-        }
-
-        return dependencyMap;
-    }
-
-    /**
-     * Computes which classes FQCN were found as dependencies that are NOT listed
-     * in the original JAR classes.
-     *
-     * @param deps The map { FQCN => dependencies[] } returned by {@link #findClassesDeps(Map)}.
-     * @param zipClasses The set of all classes FQCN found in the JAR files.
-     * @return A map { FQCN not found in the zipClasses => classes using it }
-     */
-    private Map<String, Set<String>> findMissingClasses(
-            Map<String, Set<String>> deps,
-            Set<String> zipClasses) {
-        Map<String, Set<String>> missing = new TreeMap<>();
-
-        for (Entry<String, Set<String>> entry : deps.entrySet()) {
-            String name = entry.getKey();
-
-            for (String dep : entry.getValue()) {
-                if (!zipClasses.contains(dep)) {
-                    // This dependency doesn't exist in the zip classes.
-                    Set<String> set = missing.get(dep);
-                    if (set == null) {
-                        set = new TreeSet<>();
-                        missing.put(dep, set);
-                    }
-                    set.add(name);
-                }
-            }
-
-        }
-
-        return missing;
-    }
-
-
-    // ----------------------------------
-
-    /**
-     * Instantiates a new DependencyVisitor. Useful for unit tests.
-     */
-    @VisibleForTesting(visibility=Visibility.PRIVATE)
-    DependencyVisitor getVisitor() {
-        return new DependencyVisitor();
-    }
-
-    /**
-     * Visitor to collect all the type dependencies from a class.
-     */
-    public class DependencyVisitor extends ClassVisitor {
-
-        private Set<String> mCurrentDepSet;
-
-        /**
-         * Creates a new visitor that will find all the dependencies for the visited class.
-         */
-        public DependencyVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        /**
-         * Sets the {@link Set} where to record direct dependencies for this class.
-         * This will change before each {@link ClassReader#accept(ClassVisitor, int)} call.
-         */
-        public void setDependencySet(Set<String> set) {
-            mCurrentDepSet = set;
-        }
-
-        /**
-         * Considers the given class name as a dependency.
-         */
-        public void considerName(String className) {
-            if (className == null) {
-                return;
-            }
-
-            className = internalToBinaryClassName(className);
-
-            try {
-                // exclude classes that are part of the default JRE (the one executing this program)
-                // or in java package (we won't be able to load them anyway).
-                if (className.startsWith("java.") ||
-                        getClass().getClassLoader().loadClass(className) != null) {
-                    return;
-                }
-            } catch (ClassNotFoundException e) {
-                // ignore
-            }
-
-            // Add it to the dependency set for the currently visited class, as needed.
-            assert mCurrentDepSet != null;
-            mCurrentDepSet.add(className);
-        }
-
-        /**
-         * Considers this array of names using considerName().
-         */
-        public void considerNames(String[] classNames) {
-            if (classNames != null) {
-                for (String className : classNames) {
-                    considerName(className);
-                }
-            }
-        }
-
-        /**
-         * Considers this signature or type signature by invoking the {@link SignatureVisitor}
-         * on it.
-         */
-        public void considerSignature(String signature) {
-            if (signature != null) {
-                SignatureReader sr = new SignatureReader(signature);
-                // SignatureReader.accept will call accessType so we don't really have
-                // to differentiate where the signature comes from.
-                sr.accept(new MySignatureVisitor());
-            }
-        }
-
-        /**
-         * Considers this {@link Type}. For arrays, the element type is considered.
-         * If the type is an object, it's internal name is considered.
-         */
-        public void considerType(Type t) {
-            if (t != null) {
-                if (t.getSort() == Type.ARRAY) {
-                    t = t.getElementType();
-                }
-                if (t.getSort() == Type.OBJECT) {
-                    considerName(t.getInternalName());
-                }
-            }
-        }
-
-        /**
-         * Considers a descriptor string. The descriptor is converted to a {@link Type}
-         * and then considerType() is invoked.
-         */
-        public boolean considerDesc(String desc) {
-            if (desc != null) {
-                try {
-                    if (desc.length() > 0 && desc.charAt(0) == '(') {
-                        // This is a method descriptor with arguments and a return type.
-                        Type t = Type.getReturnType(desc);
-                        considerType(t);
-
-                        for (Type arg : Type.getArgumentTypes(desc)) {
-                            considerType(arg);
-                        }
-
-                    } else {
-                        Type t = Type.getType(desc);
-                        considerType(t);
-                    }
-                    return true;
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // ignore, not a valid type.
-                }
-            }
-            return false;
-        }
-
-
-        // ---------------------------------------------------
-        // --- ClassVisitor, FieldVisitor
-        // ---------------------------------------------------
-
-        // Visits a class header
-        @Override
-        public void visit(int version, int access, String name,
-                String signature, String superName, String[] interfaces) {
-            // signature is the signature of this class. May be null if the class is not a generic
-            // one, and does not extend or implement generic classes or interfaces.
-
-            if (signature != null) {
-                considerSignature(signature);
-            }
-
-            // superName is the internal of name of the super class (see getInternalName).
-            // For interfaces, the super class is Object. May be null but only for the Object class.
-            considerName(superName);
-
-            // interfaces is the internal names of the class's interfaces (see getInternalName).
-            // May be null.
-            considerNames(interfaces);
-        }
-
-
-        @Override
-        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return new MyAnnotationVisitor();
-        }
-
-        @Override
-        public void visitAttribute(Attribute attr) {
-            // pass
-        }
-
-        // Visits the end of a class
-        @Override
-        public void visitEnd() {
-            // pass
-        }
-
-        private class MyFieldVisitor extends FieldVisitor {
-
-            public MyFieldVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitAttribute(Attribute attr) {
-                // pass
-            }
-
-            // Visits the end of a class
-            @Override
-            public void visitEnd() {
-                // pass
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-
-            // signature is the field's signature. May be null if the field's type does not use
-            // generic types.
-            considerSignature(signature);
-
-            return new MyFieldVisitor();
-        }
-
-        @Override
-        public void visitInnerClass(String name, String outerName, String innerName, int access) {
-            // name is the internal name of an inner class (see getInternalName).
-            // Note: outerName/innerName seems to be null when we're reading the
-            // _Original_ClassName classes generated by layoutlib_create.
-            if (outerName != null) {
-                considerName(name);
-            }
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-            // signature is the method's signature. May be null if the method parameters, return
-            // type and exceptions do not use generic types.
-            considerSignature(signature);
-
-            return new MyMethodVisitor();
-        }
-
-        @Override
-        public void visitOuterClass(String owner, String name, String desc) {
-            // pass
-        }
-
-        @Override
-        public void visitSource(String source, String debug) {
-            // pass
-        }
-
-
-        // ---------------------------------------------------
-        // --- MethodVisitor
-        // ---------------------------------------------------
-
-        private class MyMethodVisitor extends MethodVisitor {
-
-            public MyMethodVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-
-            @Override
-            public AnnotationVisitor visitAnnotationDefault() {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitCode() {
-                // pass
-            }
-
-            // field instruction
-            @Override
-            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                // owner is the class that declares the field.
-                considerName(owner);
-                // desc is the field's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            @Override
-            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-                // pass
-            }
-
-            @Override
-            public void visitIincInsn(int var, int increment) {
-                // pass -- an IINC instruction
-            }
-
-            @Override
-            public void visitInsn(int opcode) {
-                // pass -- a zero operand instruction
-            }
-
-            @Override
-            public void visitIntInsn(int opcode, int operand) {
-                // pass -- a single int operand instruction
-            }
-
-            @Override
-            public void visitJumpInsn(int opcode, Label label) {
-                // pass -- a jump instruction
-            }
-
-            @Override
-            public void visitLabel(Label label) {
-                // pass -- a label target
-            }
-
-            // instruction to load a constant from the stack
-            @Override
-            public void visitLdcInsn(Object cst) {
-                if (cst instanceof Type) {
-                    considerType((Type) cst);
-                }
-            }
-
-            @Override
-            public void visitLineNumber(int line, Label start) {
-                // pass
-            }
-
-            @Override
-            public void visitLocalVariable(String name, String desc,
-                    String signature, Label start, Label end, int index) {
-                // desc is the type descriptor of this local variable.
-                considerDesc(desc);
-                // signature is the type signature of this local variable. May be null if the local
-                // variable type does not use generic types.
-                considerSignature(signature);
-            }
-
-            @Override
-            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-                // pass -- a lookup switch instruction
-            }
-
-            @Override
-            public void visitMaxs(int maxStack, int maxLocals) {
-                // pass
-            }
-
-            // instruction that invokes a method
-            @Override
-            public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                    boolean itf) {
-
-                // owner is the internal name of the method's owner class
-                if (!considerDesc(owner) && owner.indexOf('/') != -1) {
-                    considerName(owner);
-                }
-                // desc is the method's descriptor (see Type).
-                considerDesc(desc);
-            }
-
-            // instruction multianewarray, whatever that is
-            @Override
-            public void visitMultiANewArrayInsn(String desc, int dims) {
-
-                // desc an array type descriptor.
-                considerDesc(desc);
-            }
-
-            @Override
-            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                    boolean visible) {
-                // desc is the class descriptor of the annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-                // pass -- table switch instruction
-
-            }
-
-            @Override
-            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-                // type is the internal name of the type of exceptions handled by the handler,
-                // or null to catch any exceptions (for "finally" blocks).
-                considerName(type);
-            }
-
-            // type instruction
-            @Override
-            public void visitTypeInsn(int opcode, String type) {
-                // type is the operand of the instruction to be visited. This operand must be the
-                // internal name of an object or array class.
-                considerName(type);
-            }
-
-            @Override
-            public void visitVarInsn(int opcode, int var) {
-                // pass -- local variable instruction
-            }
-        }
-
-        private class MySignatureVisitor extends SignatureVisitor {
-
-            public MySignatureVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // ---------------------------------------------------
-            // --- SignatureVisitor
-            // ---------------------------------------------------
-
-            private String mCurrentSignatureClass = null;
-
-            // Starts the visit of a signature corresponding to a class or interface type
-            @Override
-            public void visitClassType(String name) {
-                mCurrentSignatureClass = name;
-                considerName(name);
-            }
-
-            // Visits an inner class
-            @Override
-            public void visitInnerClassType(String name) {
-                if (mCurrentSignatureClass != null) {
-                    mCurrentSignatureClass += "$" + name;
-                    considerName(mCurrentSignatureClass);
-                }
-            }
-
-            @Override
-            public SignatureVisitor visitArrayType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitBaseType(char descriptor) {
-                // pass -- a primitive type, ignored
-            }
-
-            @Override
-            public SignatureVisitor visitClassBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitExceptionType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitFormalTypeParameter(String name) {
-                // pass
-            }
-
-            @Override
-            public SignatureVisitor visitInterface() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitInterfaceBound() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitParameterType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitReturnType() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitSuperclass() {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public SignatureVisitor visitTypeArgument(char wildcard) {
-                return new MySignatureVisitor();
-            }
-
-            @Override
-            public void visitTypeVariable(String name) {
-                // pass
-            }
-
-            @Override
-            public void visitTypeArgument() {
-                // pass
-            }
-        }
-
-
-        // ---------------------------------------------------
-        // --- AnnotationVisitor
-        // ---------------------------------------------------
-
-        private class MyAnnotationVisitor extends AnnotationVisitor {
-
-            public MyAnnotationVisitor() {
-                super(Main.ASM_VERSION);
-            }
-
-            // Visits a primitive value of an annotation
-            @Override
-            public void visit(String name, Object value) {
-                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-                // Integer, Long, Float, Double, String or Type
-                if (value instanceof Type) {
-                    considerType((Type) value);
-                }
-            }
-
-            @Override
-            public AnnotationVisitor visitAnnotation(String name, String desc) {
-                // desc is the class descriptor of the nested annotation class.
-                considerDesc(desc);
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public AnnotationVisitor visitArray(String name) {
-                return new MyAnnotationVisitor();
-            }
-
-            @Override
-            public void visitEnum(String name, String desc, String value) {
-                // desc is the class descriptor of the enumeration class.
-                considerDesc(desc);
-            }
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
deleted file mode 100644
index 4608a84..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/FieldInjectorAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Injects fields in a class.
- * <p>
- * TODO: Generify
- */
-public class FieldInjectorAdapter extends ClassVisitor {
-    public FieldInjectorAdapter(ClassVisitor cv) {
-        super(Opcodes.ASM4, cv);
-    }
-
-    @Override
-    public void visitEnd() {
-        super.visitField(Opcodes.ACC_PUBLIC, "mLayoutlibCallback",
-                "Lcom/android/ide/common/rendering/api/LayoutlibCallback;", null, null);
-        super.visitField(Opcodes.ACC_PUBLIC, "mContext",
-                "Lcom/android/layoutlib/bridge/android/BridgeContext;", null, null);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
deleted file mode 100644
index eca1c07..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Interface describing the work to be done by {@link AsmGenerator}.
- */
-public interface ICreateInfo {
-
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
-    Class<?>[] getInjectedClasses();
-
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateMethods();
-
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
-    String[] getDelegateClassNatives();
-
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
-    String[] getRenamedClasses();
-
-    /**
-     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
-     * {@link #getJavaPkgClasses()}.
-     * Classes included here will be renamed and then all their references in any other classes
-     * will be also modified.
-     * FQCN of class to refactor followed by its new FQCN.
-     */
-    String[] getRefactoredClasses();
-
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
-    String[] getDeleteReturns();
-
-    /**
-     * Returns the list of classes to refactor, must be an even list: the
-     * binary FQCN of class to replace followed by the new FQCN. All references
-     * to the old class should be updated to the new class.
-     * The list can be empty but must not be null.
-     */
-    String[] getJavaPkgClasses();
-
-    Set<String> getExcludedClasses();
-
-    /**
-     * Returns a list of fields which should be promoted to public visibility. The array values
-     * are in the form of the binary FQCN of the class containing the field and the field name
-     * separated by a '#'.
-     */
-    String[] getPromotedFields();
-
-    /**
-     * Returns a list of classes to be promoted to public visibility.
-     */
-    String[] getPromotedClasses();
-
-    /**
-     * Returns a map from binary FQCN className to {@link InjectMethodRunnable} which will be
-     * called to inject methods into a class.
-     * Can be empty but must not be null.
-     */
-    Map<String, InjectMethodRunnable> getInjectedMethodsMap();
-
-    abstract class InjectMethodRunnable {
-        /**
-         * @param cv Must be {@link ClassVisitor}. However, the param type is object so that when
-         * loading the class, ClassVisitor is not loaded. This is because when injecting
-         * CreateInfo in LayoutLib (see {@link #getInjectedClasses()}, we don't want to inject
-         * asm classes also, but still keep CreateInfo loadable.
-         */
-        public abstract void generateMethods(Object cv);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
deleted file mode 100644
index 1941ab4..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodRunnables.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ARETURN;
-import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
-
-public class InjectMethodRunnables {
-    public static final ICreateInfo.InjectMethodRunnable CONTEXT_GET_FRAMEWORK_CLASS_LOADER
-            = new InjectMethodRunnable() {
-        @Override
-        public void generateMethods(Object classVisitor) {
-            assert classVisitor instanceof ClassVisitor;
-            ClassVisitor cv = (ClassVisitor) classVisitor;
-            // generated by compiling the class:
-            // class foo { public ClassLoader getFrameworkClassLoader() { return getClass().getClassLoader(); } }
-            // and then running ASMifier on it:
-            // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo
-            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "getFrameworkClassLoader",
-                    "()Ljava/lang/ClassLoader;", null, null);
-            mv.visitCode();
-            mv.visitVarInsn(ALOAD, 0);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass",
-                    "()Ljava/lang/Class;", false);
-            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader",
-                    "()Ljava/lang/ClassLoader;", false);
-            mv.visitInsn(ARETURN);
-            mv.visitMaxs(1, 1);
-            mv.visitEnd();
-            // generated code ends.
-        }
-    };
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
deleted file mode 100644
index c834808..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/InjectMethodsAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.ICreateInfo.InjectMethodRunnable;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * Injects methods into some classes.
- */
-public class InjectMethodsAdapter extends ClassVisitor {
-
-    private final ICreateInfo.InjectMethodRunnable mRunnable;
-
-    public InjectMethodsAdapter(ClassVisitor cv, InjectMethodRunnable runnable) {
-        super(Main.ASM_VERSION, cv);
-        mRunnable = runnable;
-    }
-
-    @Override
-    public void visitEnd() {
-        mRunnable.generateMethods(this);
-        super.visitEnd();
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
deleted file mode 100644
index c3ba591..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Log.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class Log {
-
-    private boolean mVerbose = false;
-
-    public void setVerbose(boolean verbose) {
-        mVerbose = verbose;
-    }
-
-    public void debug(String format, Object... args) {
-        if (mVerbose) {
-            info(format, args);
-        }
-    }
-
-    /** Similar to debug() but doesn't do a \n automatically. */
-    public void debugNoln(String format, Object... args) {
-        if (mVerbose) {
-            String s = String.format(format, args);
-            System.out.print(s);
-        }
-    }
-
-    public void info(String format, Object... args) {
-        String s = String.format(format, args);
-        outPrintln(s);
-    }
-
-    public void error(String format, Object... args) {
-        String s = String.format(format, args);
-        errPrintln(s);
-    }
-
-    public void exception(Throwable t, String format, Object... args) {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        t.printStackTrace(pw);
-        pw.flush();
-        error(format + "\n" + sw.toString(), args);
-    }
-
-    /** for unit testing */
-    protected void errPrintln(String msg) {
-        System.err.println(msg);
-    }
-
-    /** for unit testing */
-    protected void outPrintln(String msg) {
-        System.out.println(msg);
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
deleted file mode 100644
index dc4b4a7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/LogAbortException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-public class LogAbortException extends Exception {
-
-    private final String mFormat;
-    private final Object[] mArgs;
-
-    public LogAbortException(String format, Object... args) {
-        mFormat = format;
-        mArgs = args;
-    }
-    
-    public void error(Log log) {
-        log.error(mFormat, mArgs);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
deleted file mode 100644
index 4b6cf43..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * Entry point for the layoutlib_create tool.
- * <p/>
- * The tool does not currently rely on any external configuration file.
- * Instead the configuration is mostly done via the {@link CreateInfo} class.
- * <p/>
- * For a complete description of the tool and its implementation, please refer to
- * the "README.txt" file at the root of this project.
- * <p/>
- * For a quick test, invoke this as follows:
- * <pre>
- * $ make layoutlib
- * </pre>
- * which does:
- * <pre>
- * $ make layoutlib_create &lt;bunch of framework jars&gt;
- * $ java -jar out/host/linux-x86/framework/layoutlib_create.jar \
- *        out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar \
- *        out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- * </pre>
- */
-public class Main {
-
-    public static class Options {
-        public boolean listAllDeps = false;
-        public boolean listOnlyMissingDeps = false;
-    }
-
-    public static final int ASM_VERSION = Opcodes.ASM5;
-
-    public static final Options sOptions = new Options();
-
-    public static void main(String[] args) {
-
-        Log log = new Log();
-
-        ArrayList<String> osJarPath = new ArrayList<>();
-        String[] osDestJar = { null };
-
-        if (!processArgs(log, args, osJarPath, osDestJar)) {
-            log.error("Usage: layoutlib_create [-v] output.jar input.jar ...");
-            log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
-            System.exit(1);
-        }
-
-        if (sOptions.listAllDeps || sOptions.listOnlyMissingDeps) {
-            System.exit(listDeps(osJarPath, log));
-
-        } else {
-            System.exit(createLayoutLib(osDestJar[0], osJarPath, log));
-        }
-
-
-        System.exit(1);
-    }
-
-    private static int createLayoutLib(String osDestJar, ArrayList<String> osJarPath, Log log) {
-        log.info("Output: %1$s", osDestJar);
-        for (String path : osJarPath) {
-            log.info("Input :      %1$s", path);
-        }
-
-        try {
-            CreateInfo info = new CreateInfo();
-            Set<String> excludeClasses = info.getExcludedClasses();
-            AsmGenerator agen = new AsmGenerator(log, osDestJar, info);
-
-            AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
-                    new String[] {                          // derived from
-                        "android.view.View",
-                        "android.app.Fragment"
-                    },
-                    new String[] {                          // include classes
-                        "android.*", // for android.R
-                        "android.util.*",
-                        "com.android.internal.util.*",
-                        "android.view.*",
-                        "android.widget.*",
-                        "com.android.internal.widget.*",
-                        "android.text.**",
-                        "android.graphics.*",
-                        "android.graphics.drawable.**",
-                        "android.content.*",
-                        "android.content.res.*",
-                        "android.preference.*",
-                        "org.apache.harmony.xml.*",
-                        "com.android.internal.R**",
-                        "android.pim.*", // for datepicker
-                        "android.os.*",  // for android.os.Handler
-                        "android.database.ContentObserver", // for Digital clock
-                        "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
-                        "android.app.DatePickerDialog",     // b.android.com/28318
-                        "android.app.TimePickerDialog",     // b.android.com/61515
-                        "com.android.internal.view.menu.ActionMenu",
-                        "android.icu.**",                   // needed by LayoutLib
-                        "android.annotation.NonNull",       // annotations
-                        "android.annotation.Nullable",      // annotations
-                        "com.android.internal.transition.EpicenterTranslateClipReveal",
-                        "com.android.internal.graphics.drawable.AnimationScaleListDrawable",
-                    },
-                    excludeClasses,
-                    new String[] {
-                        "com/android/i18n/phonenumbers/data/*",
-                        "android/icu/impl/data/**"
-                    });
-            aa.analyze();
-            agen.generate();
-
-            // Throw an error if any class failed to get renamed by the generator
-            //
-            // IMPORTANT: if you're building the platform and you get this error message,
-            // it means the renameClasses[] array in AsmGenerator needs to be updated: some
-            // class should have been renamed but it was not found in the input JAR files.
-            Set<String> notRenamed = agen.getClassesNotRenamed();
-            if (notRenamed.size() > 0) {
-                // (80-column guide below for error formatting)
-                // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
-                log.error(
-                  "ERROR when running layoutlib_create: the following classes are referenced\n" +
-                  "by tools/layoutlib/create but were not actually found in the input JAR files.\n" +
-                  "This may be due to some platform classes having been renamed.");
-                for (String fqcn : notRenamed) {
-                    log.error("- Class not found: %s", fqcn.replace('/', '.'));
-                }
-                for (String path : osJarPath) {
-                    log.info("- Input JAR : %1$s", path);
-                }
-                return 1;
-            }
-
-            return 0;
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        } catch (LogAbortException e) {
-            e.error(log);
-        }
-
-        return 1;
-    }
-
-    private static int listDeps(ArrayList<String> osJarPath, Log log) {
-        DependencyFinder df = new DependencyFinder(log);
-        try {
-            List<Map<String, Set<String>>> result = df.findDeps(osJarPath);
-            if (sOptions.listAllDeps) {
-                df.printAllDeps(result);
-            } else if (sOptions.listOnlyMissingDeps) {
-                df.printMissingDeps(result);
-            }
-        } catch (IOException e) {
-            log.exception(e, "Failed to load jar");
-        }
-
-        return 0;
-    }
-
-    /**
-     * Returns true if args where properly parsed.
-     * Returns false if program should exit with command-line usage.
-     * <p/>
-     * Note: the String[0] is an output parameter wrapped in an array, since there is no
-     * "out" parameter support.
-     */
-    private static boolean processArgs(Log log, String[] args,
-            ArrayList<String> osJarPath, String[] osDestJar) {
-        boolean needs_dest = true;
-        for (String s : args) {
-            if (s.equals("-v")) {
-                log.setVerbose(true);
-            } else if (s.equals("--list-deps")) {
-                sOptions.listAllDeps = true;
-                needs_dest = false;
-            } else if (s.equals("--missing-deps")) {
-                sOptions.listOnlyMissingDeps = true;
-                needs_dest = false;
-            } else if (!s.startsWith("-")) {
-                if (needs_dest && osDestJar[0] == null) {
-                    osDestJar[0] = s;
-                } else {
-                    osJarPath.add(s);
-                }
-            } else {
-                log.error("Unknown argument: %s", s);
-                return false;
-            }
-        }
-
-        if (osJarPath.isEmpty()) {
-            log.error("Missing parameter: path to input jar");
-            return false;
-        }
-        if (needs_dest && osDestJar[0] == null) {
-            log.error("Missing parameter: path to output jar");
-            return false;
-        }
-
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
deleted file mode 100644
index 7d1e4cf..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodAdapter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-/**
- * An adapter to make it easier to use {@link MethodListener}.
- * <p/>
- * The adapter calls the void {@link #onInvokeV(String, boolean, Object)} listener
- * for all types (I, L, F, D and A), returning 0 or null as appropriate.
- */
-public class MethodAdapter implements MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    @Override
-    public void onInvokeV(String signature, boolean isNative, Object caller) {
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    @Override
-    public int onInvokeI(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    @Override
-    public long onInvokeL(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    @Override
-    public float onInvokeF(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    @Override
-    public double onInvokeD(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return 0;
-    }
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    @Override
-    public Object onInvokeA(String signature, boolean isNative, Object caller) {
-        onInvokeV(signature, isNative, caller);
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
deleted file mode 100644
index faba4d7..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/MethodListener.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-/**
- * Interface to allow a method invocation to be listened upon.
- * <p/>
- * This is used by {@link OverrideMethod} to register a listener for methods that
- * have been stubbed by the {@link AsmGenerator}. At runtime the stub will call either a
- * default global listener or a specific listener based on the method signature.
- */
-public interface MethodListener {
-    /**
-     * A stub method is being invoked.
-     * <p/>
-     * Known limitation: caller arguments are not available.
-     *  
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    void onInvokeV(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an integer or similar.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an integer, or a boolean, or a short or a byte.
-     */
-    int onInvokeI(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a long.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a long.
-     */
-    long onInvokeL(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a float.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a float.
-     */
-    float onInvokeF(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns a double.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return a double.
-     */
-    double onInvokeD(String signature, boolean isNative, Object caller);
-
-    /**
-     * Same as {@link #onInvokeV(String, boolean, Object)} but returns an object.
-     * @see #onInvokeV(String, boolean, Object)
-     * @return an object.
-     */
-    Object onInvokeA(String signature, boolean isNative, Object caller);
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
deleted file mode 100644
index 7ccafc3..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/OverrideMethod.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.HashMap;
-
-/**
- * Allows stub methods from LayoutLib to be overriden at runtime.
- * <p/>
- * Implementation note: all types required by this class(inner/outer classes & interfaces)
- * must be referenced by the injectClass argument to {@link AsmGenerator} in Main.java;
- * Otherwise they won't be accessible in layoutlib.jar at runtime.
- */
-public final class OverrideMethod {
-
-    /** Map of method overridden. */
-    private static HashMap<String, MethodListener> sMethods = new HashMap<>();
-    /** Default listener for all method not listed in sMethods. Nothing if null. */
-    private static MethodListener sDefaultListener = null;
-    
-    /**
-     * Sets the default listener for all methods not specifically handled.
-     * Null means to do nothing.
-     */
-    @SuppressWarnings("UnusedDeclaration") // Used by Bridge by reflection for debug purposes.
-    public static void setDefaultListener(MethodListener listener) {
-        sDefaultListener = listener;
-    }
-
-    /**
-     * Defines or reset a listener for the given method signature.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V"
-     * @param listener The new listener. Removes it if null.
-     */
-    public static void setMethodListener(String signature, MethodListener listener) {
-        if (listener == null) {
-            sMethods.remove(signature);
-        } else {
-            sMethods.put(signature, listener);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the given signature or the default one if defined.
-     * <p/>
-     * This version invokes the method listener for the void return type. 
-     * <p/>
-     * Note: this is not intended to be used by the LayoutLib Bridge. It is intended to be called
-     * by the stubbed methods generated by the LayoutLib_create tool.
-     * 
-     * @param signature The signature of the method being invoked, composed of the
-     *                  binary class name followed by the method descriptor (aka argument
-     *                  types). Example: "com/foo/MyClass/InnerClass/printInt(I)V".
-     * @param isNative True if the method was a native method.
-     * @param caller The calling object. Null for static methods, "this" for instance methods.
-     */
-    public static void invokeV(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            i.onInvokeV(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            sDefaultListener.onInvokeV(signature, isNative, caller);
-        }
-    }
-    
-    /**
-     * Invokes the specific listener for the int return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static int invokeI(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeI(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeI(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the long return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static long invokeL(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeL(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeL(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the float return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static float invokeF(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeF(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeF(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the double return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static double invokeD(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeD(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeD(signature, isNative, caller);
-        }
-        return 0;
-    }
-    
-    /**
-     * Invokes the specific listener for the object return type.
-     * @see #invokeV(String, boolean, Object)
-     */
-    public static Object invokeA(String signature, boolean isNative, Object caller) {
-        MethodListener i = sMethods.get(signature);
-        if (i != null) {
-            return i.onInvokeA(signature, isNative, caller);
-        } else if (sDefaultListener != null) {
-            return sDefaultListener.onInvokeA(signature, isNative, caller);
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
deleted file mode 100644
index 99e3089..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteClassClassAdapter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given classes to public visibility.
- */
-public class PromoteClassClassAdapter extends ClassVisitor {
-
-    private final Set<String> mClassNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteClassClassAdapter(ClassVisitor cv, Set<String> classNames) {
-        super(Main.ASM_VERSION, cv);
-        mClassNames =
-                classNames.stream().map(name -> name.replace(".", "/")).collect(Collectors.toSet());
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        if (mClassNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
deleted file mode 100644
index ba77860..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/PromoteFieldClassAdapter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-
-import java.util.Set;
-
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-
-/**
- * Promotes given fields to public visibility.
- */
-public class PromoteFieldClassAdapter extends ClassVisitor {
-
-    private final Set<String> mFieldNames;
-    private static final int CLEAR_PRIVATE_MASK = ~(ACC_PRIVATE | ACC_PROTECTED);
-
-    public PromoteFieldClassAdapter(ClassVisitor cv, Set<String> fieldNames) {
-        super(Main.ASM_VERSION, cv);
-        mFieldNames = fieldNames;
-    }
-
-    @Override
-    public FieldVisitor visitField(int access, String name, String desc, String signature,
-            Object value) {
-        if (mFieldNames.contains(name)) {
-            if ((access & ACC_PUBLIC) == 0) {
-                access = (access & CLEAR_PRIVATE_MASK) | ACC_PUBLIC;
-            }
-        }
-        return super.visitField(access, name, desc, signature, value);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
deleted file mode 100644
index 024e32f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RefactorClassAdapter.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-public class RefactorClassAdapter extends AbstractClassAdapter {
-
-    private final HashMap<String, String> mRefactorClasses;
-
-    RefactorClassAdapter(ClassVisitor cv, HashMap<String, String> refactorClasses) {
-        super(cv);
-        mRefactorClasses = refactorClasses;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-
-        return new RefactorStackMapAdapter(mw);
-    }
-
-    @Override
-    protected String renameInternalType(String oldClassName) {
-        if (oldClassName != null) {
-            String newName = mRefactorClasses.get(oldClassName);
-            if (newName != null) {
-                return newName;
-            }
-            int pos = oldClassName.indexOf('$');
-            if (pos > 0) {
-                newName = mRefactorClasses.get(oldClassName.substring(0, pos));
-                if (newName != null) {
-                    return newName + oldClassName.substring(pos);
-                }
-            }
-        }
-        return oldClassName;
-    }
-
-    /**
-     * A method visitor that renames all references from an old class name to a new class name in
-     * the stackmap of the method.
-     */
-    private class RefactorStackMapAdapter extends MethodVisitor {
-
-        private RefactorStackMapAdapter(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-
-        private Object[] renameFrame(Object[] elements) {
-            if (elements == null) {
-                return null;
-            }
-
-            // The input array cannot be modified. We only copy the source array on write
-            boolean copied = false;
-            for (int i = 0; i < elements.length; i++) {
-                if (!(elements[i] instanceof String)) {
-                    continue;
-                }
-
-                if (!copied) {
-                    elements = Arrays.copyOf(elements, elements.length);
-                    copied = true;
-                }
-
-                String type = (String)elements[i];
-                if (type.indexOf(';') > 0) {
-                    elements[i] = renameTypeDesc(type);
-                } else {
-                    elements[i] = renameInternalType(type);
-                }
-            }
-
-            return elements;
-        }
-
-        @Override
-        public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-            super.visitFrame(type, nLocal, renameFrame(local), nStack, renameFrame(stack));
-        }
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
deleted file mode 100644
index 40bd126..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * This class visitor renames a class from a given old name to a given new name.
- * The class visitor will also rename all inner classes and references in the methods.
- * <p/>
- *
- * For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same.
- */
-public class RenameClassAdapter extends AbstractClassAdapter {
-
-
-    private final String mOldName;
-    private final String mNewName;
-    private String mOldBase;
-    private String mNewBase;
-
-    /**
-     * Creates a class visitor that renames a class from a given old name to a given new name.
-     * The class visitor will also rename all inner classes and references in the methods.
-     * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
-     */
-    public RenameClassAdapter(ClassVisitor cv, String oldName, String newName) {
-        super(cv);
-        mOldBase = mOldName = oldName;
-        mNewBase = mNewName = newName;
-
-        int pos = mOldName.indexOf('$');
-        if (pos > 0) {
-            mOldBase = mOldName.substring(0, pos);
-        }
-        pos = mNewName.indexOf('$');
-        if (pos > 0) {
-            mNewBase = mNewName.substring(0, pos);
-        }
-
-        assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     * <p/>
-     * The internal type of some of the MethodVisitor turns out to be a type
-       descriptor sometimes so descriptors are renamed too.
-     */
-    @Override
-    protected String renameInternalType(String type) {
-        if (type == null) {
-            return null;
-        }
-
-        if (type.equals(mOldName)) {
-            return mNewName;
-        }
-
-        if (!mOldBase.equals(mOldName) && type.equals(mOldBase)) {
-            return mNewBase;
-        }
-
-        int pos = type.indexOf('$');
-        if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
-            return mNewBase + type.substring(pos);
-        }
-        return type;
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
deleted file mode 100644
index bf94415..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ReplaceMethodCallsAdapter.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.System_Delegate;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Replaces calls to certain methods that do not exist in the Desktop VM. Useful for methods in the
- * "java" package.
- */
-public class ReplaceMethodCallsAdapter extends ClassVisitor {
-
-    /**
-     * Descriptors for specialized versions {@link System#arraycopy} that are not present on the
-     * Desktop VM.
-     */
-    private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<>(Arrays.asList(
-            "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V",
-            "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V"));
-
-    private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<>(5);
-
-    private static final String ANDROID_LOCALE_CLASS =
-            "com/android/layoutlib/bridge/android/AndroidLocale";
-
-    private static final String JAVA_LOCALE_CLASS = Type.getInternalName(java.util.Locale.class);
-    private static final Type STRING = Type.getType(String.class);
-
-    private static final String JAVA_LANG_SYSTEM = Type.getInternalName(System.class);
-
-    // Static initialization block to initialize METHOD_REPLACERS.
-    static {
-        // Case 1: java.lang.System.arraycopy()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && "arraycopy".equals(name) &&
-                        ARRAYCOPY_DESCRIPTORS.contains(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
-            }
-        });
-
-        // Case 2: java.util.Locale.toLanguageTag() and java.util.Locale.getScript()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String LOCALE_TO_STRING =
-                    Type.getMethodDescriptor(STRING, Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) && "()Ljava/lang/String;".equals(desc) &&
-                        ("toLanguageTag".equals(name) || "getScript".equals(name));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = ANDROID_LOCALE_CLASS;
-                mi.desc = LOCALE_TO_STRING;
-            }
-        });
-
-        // Case 3: java.util.Locale.adjustLanguageCode() or java.util.Locale.forLanguageTag() or
-        // java.util.Locale.getDefault()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String STRING_TO_STRING = Type.getMethodDescriptor(STRING, STRING);
-            private final String STRING_TO_LOCALE = Type.getMethodDescriptor(
-                    Type.getType(Locale.class), STRING);
-            private final String VOID_TO_LOCALE =
-                    Type.getMethodDescriptor(Type.getType(Locale.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LOCALE_CLASS.equals(owner) &&
-                        ("adjustLanguageCode".equals(name) && desc.equals(STRING_TO_STRING) ||
-                        "forLanguageTag".equals(name) && desc.equals(STRING_TO_LOCALE) ||
-                        "getDefault".equals(name) && desc.equals(VOID_TO_LOCALE));
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.owner = ANDROID_LOCALE_CLASS;
-            }
-        });
-
-        // Case 4: java.lang.System.log?()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.length() == 4
-                        && name.startsWith("log");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                assert mi.desc.equals("(Ljava/lang/String;Ljava/lang/Throwable;)V")
-                        || mi.desc.equals("(Ljava/lang/String;)V");
-                mi.name = "log";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 5: java.lang.System time calls
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("nanoTime");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "nanoTime";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return JAVA_LANG_SYSTEM.equals(owner) && name.equals("currentTimeMillis");
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "currentTimeMillis";
-                mi.owner = Type.getInternalName(System_Delegate.class);
-            }
-        });
-
-        // Case 6: java.util.LinkedHashMap.eldest()
-        METHOD_REPLACERS.add(new MethodReplacer() {
-
-            private final String VOID_TO_MAP_ENTRY =
-                    Type.getMethodDescriptor(Type.getType(Map.Entry.class));
-            private final String LINKED_HASH_MAP = Type.getInternalName(LinkedHashMap.class);
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return LINKED_HASH_MAP.equals(owner) &&
-                        "eldest".equals(name) &&
-                        VOID_TO_MAP_ENTRY.equals(desc);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.opcode = Opcodes.INVOKESTATIC;
-                mi.owner = Type.getInternalName(LinkedHashMap_Delegate.class);
-                mi.desc = Type.getMethodDescriptor(
-                        Type.getType(Map.Entry.class), Type.getType(LinkedHashMap.class));
-            }
-        });
-
-        // Case 7: android.content.Context.getClassLoader() in LayoutInflater
-        METHOD_REPLACERS.add(new MethodReplacer() {
-            // When LayoutInflater asks for a class loader, we must return the class loader that
-            // cannot return app's custom views/classes. This is so that in case of any failure
-            // or exception when instantiating the views, the IDE can replace it with a mock view
-            // and have proper error handling. However, if a custom view asks for the class
-            // loader, we must return a class loader that can find app's custom views as well.
-            // Thus, we rewrite the call to get class loader in LayoutInflater to
-            // getFrameworkClassLoader and inject a new method in Context. This leaves the normal
-            // method: Context.getClassLoader() free to be used by the apps.
-            private final String VOID_TO_CLASS_LOADER =
-                    Type.getMethodDescriptor(Type.getType(ClassLoader.class));
-
-            @Override
-            public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
-                return owner.equals("android/content/Context") &&
-                        sourceClass.equals("android/view/LayoutInflater") &&
-                        name.equals("getClassLoader") &&
-                        desc.equals(VOID_TO_CLASS_LOADER);
-            }
-
-            @Override
-            public void replace(MethodInformation mi) {
-                mi.name = "getFrameworkClassLoader";
-            }
-        });
-    }
-
-    /**
-     * If a method some.package.Class.Method(args) is called from some.other.Class,
-     * @param owner some/package/Class
-     * @param name Method
-     * @param desc (args)returnType
-     * @param sourceClass some/other/Class
-     * @return if the method invocation needs to be replaced by some other class.
-     */
-    public static boolean isReplacementNeeded(String owner, String name, String desc,
-            String sourceClass) {
-        for (MethodReplacer replacer : METHOD_REPLACERS) {
-            if (replacer.isNeeded(owner, name, desc, sourceClass)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private final String mOriginalClassName;
-
-    public ReplaceMethodCallsAdapter(ClassVisitor cv, String originalClassName) {
-        super(Main.ASM_VERSION, cv);
-        mOriginalClassName = originalClassName;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-            String[] exceptions) {
-        return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
-    }
-
-    private class MyMethodVisitor extends MethodVisitor {
-
-        public MyMethodVisitor(MethodVisitor mv) {
-            super(Main.ASM_VERSION, mv);
-        }
-
-        @Override
-        public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                boolean itf) {
-            for (MethodReplacer replacer : METHOD_REPLACERS) {
-                if (replacer.isNeeded(owner, name, desc, mOriginalClassName)) {
-                    MethodInformation mi = new MethodInformation(opcode, owner, name, desc);
-                    replacer.replace(mi);
-                    opcode = mi.opcode;
-                    owner = mi.owner;
-                    name = mi.name;
-                    desc = mi.desc;
-                    break;
-                }
-            }
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    private static class MethodInformation {
-        public int opcode;
-        public String owner;
-        public String name;
-        public String desc;
-
-        public MethodInformation(int opcode, String owner, String name, String desc) {
-            this.opcode = opcode;
-            this.owner = owner;
-            this.name = name;
-            this.desc = desc;
-        }
-    }
-
-    private interface MethodReplacer {
-        boolean isNeeded(String owner, String name, String desc, String sourceClass);
-
-        /**
-         * Updates the MethodInformation with the new values of the method attributes -
-         * opcode, owner, name and desc.
-         */
-        void replace(MethodInformation mi);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
deleted file mode 100644
index 4ba7237..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * This method adapter rewrites a method by discarding the original code and generating
- * a stub depending on the return type. Original annotations are passed along unchanged.
- */
-class StubMethodAdapter extends MethodVisitor {
-
-    private static final String CONSTRUCTOR = "<init>";
-    private static final String CLASS_INIT = "<clinit>";
-
-    /** The parent method writer */
-    private MethodVisitor mParentVisitor;
-    /** The method return type. Can be null. */
-    private Type mReturnType;
-    /** Message to be printed by stub methods. */
-    private String mInvokeSignature;
-    /** Flag to output the first line number. */
-    private boolean mOutputFirstLineNumber = true;
-    /** Flag that is true when implementing a constructor, to accept all original
-     *  code calling the original super constructor. */
-    private boolean mIsInitMethod = false;
-
-    private boolean mMessageGenerated;
-    private final boolean mIsStatic;
-    private final boolean mIsNative;
-
-    public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
-            String invokeSignature, boolean isStatic, boolean isNative) {
-        super(Main.ASM_VERSION);
-        mParentVisitor = mv;
-        mReturnType = returnType;
-        mInvokeSignature = invokeSignature;
-        mIsStatic = isStatic;
-        mIsNative = isNative;
-
-        if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
-            mIsInitMethod = true;
-        }
-    }
-
-    private void generateInvoke() {
-        /* Generates the code:
-         *  OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
-         */
-        mParentVisitor.visitLdcInsn(mInvokeSignature);
-        // push true or false
-        mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
-        // push null or this
-        if (mIsStatic) {
-            mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
-        }
-
-        int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
-        switch(sort) {
-        case Type.VOID:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeV",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)V",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.RETURN);
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeI",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)I",
-                    false);
-            switch(sort) {
-            case Type.BOOLEAN:
-                Label l1 = new Label();
-                mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
-                mParentVisitor.visitInsn(Opcodes.ICONST_1);
-                mParentVisitor.visitInsn(Opcodes.IRETURN);
-                mParentVisitor.visitLabel(l1);
-                mParentVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
-                mParentVisitor.visitInsn(Opcodes.ICONST_0);
-                break;
-            case Type.CHAR:
-                mParentVisitor.visitInsn(Opcodes.I2C);
-                break;
-            case Type.BYTE:
-                mParentVisitor.visitInsn(Opcodes.I2B);
-                break;
-            case Type.SHORT:
-                mParentVisitor.visitInsn(Opcodes.I2S);
-                break;
-            }
-            mParentVisitor.visitInsn(Opcodes.IRETURN);
-            break;
-        case Type.LONG:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeL",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)J",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.LRETURN);
-            break;
-        case Type.FLOAT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeF",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)F",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.FRETURN);
-            break;
-        case Type.DOUBLE:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeD",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)D",
-                    false);
-            mParentVisitor.visitInsn(Opcodes.DRETURN);
-            break;
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
-                    "com/android/tools/layoutlib/create/OverrideMethod",
-                    "invokeA",
-                    "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;",
-                    false);
-            mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
-            mParentVisitor.visitInsn(Opcodes.ARETURN);
-            break;
-        }
-
-    }
-
-    private void generatePop() {
-        /* Pops the stack, depending on the return type.
-         */
-        switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) {
-        case Type.VOID:
-            break;
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-        case Type.FLOAT:
-        case Type.ARRAY:
-        case Type.OBJECT:
-            mParentVisitor.visitInsn(Opcodes.POP);
-            break;
-        case Type.LONG:
-        case Type.DOUBLE:
-            mParentVisitor.visitInsn(Opcodes.POP2);
-            break;
-        }
-    }
-
-    /* Pass down to visitor writer. In this implementation, either do nothing. */
-    @Override
-    public void visitCode() {
-        mParentVisitor.visitCode();
-    }
-
-    /*
-     * visitMaxs is called just before visitEnd if there was any code to rewrite.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-        }
-        mParentVisitor.visitMaxs(maxStack, maxLocals);
-    }
-
-    /**
-     * End of visiting.
-     * For non-constructor, generate the messaging code and the return statement
-     * if it hasn't been done before.
-     */
-    @Override
-    public void visitEnd() {
-        if (!mIsInitMethod && !mMessageGenerated) {
-            generateInvoke();
-            mMessageGenerated = true;
-            mParentVisitor.visitMaxs(1, 1);
-        }
-        mParentVisitor.visitEnd();
-    }
-
-    /* Writes all annotation from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        return mParentVisitor.visitAnnotation(desc, visible);
-    }
-
-    /* Writes all annotation default values from the original method. */
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        return mParentVisitor.visitAnnotationDefault();
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-            boolean visible) {
-        return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
-    }
-
-    /* Writes all attributes from the original method. */
-    @Override
-    public void visitAttribute(Attribute attr) {
-        mParentVisitor.visitAttribute(attr);
-    }
-
-    /*
-     * Only writes the first line number present in the original code so that source
-     * viewers can direct to the correct method, even if the content doesn't match.
-     */
-    @Override
-    public void visitLineNumber(int line, Label start) {
-        if (mIsInitMethod || mOutputFirstLineNumber) {
-            mParentVisitor.visitLineNumber(line, start);
-            mOutputFirstLineNumber = false;
-        }
-    }
-
-    /**
-     * For non-constructor, rewrite existing "return" instructions to write the message.
-     */
-    @Override
-    public void visitInsn(int opcode) {
-        if (mIsInitMethod) {
-            switch (opcode) {
-            case Opcodes.RETURN:
-            case Opcodes.ARETURN:
-            case Opcodes.DRETURN:
-            case Opcodes.FRETURN:
-            case Opcodes.IRETURN:
-            case Opcodes.LRETURN:
-                // Pop the last word from the stack since invoke will generate its own return.
-                generatePop();
-                generateInvoke();
-                mMessageGenerated = true;
-                //$FALL-THROUGH$
-            default:
-                mParentVisitor.visitInsn(opcode);
-            }
-        }
-    }
-
-    @Override
-    public void visitLabel(Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLabel(label);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMethodInsn(opcode, owner, name, desc, itf);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(int var, int increment) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(int opcode, int operand) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(Object cst) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(int opcode, String type) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(int opcode, int var) {
-        if (mIsInitMethod) {
-            mParentVisitor.visitVarInsn(opcode, var);
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
deleted file mode 100644
index a28ae69..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.util.Set;
-
-/**
- * Class adapter that can stub some or all of the methods of the class.
- */
-class TransformClassAdapter extends ClassVisitor {
-
-    /** True if all methods should be stubbed, false if only native ones must be stubbed. */
-    private final boolean mStubAll;
-    /** True if the class is an interface. */
-    private boolean mIsInterface;
-    private final String mClassName;
-    private final Log mLog;
-    private final Set<String> mStubMethods;
-    private Set<String> mDeleteReturns;
-
-    /**
-     * Creates a new class adapter that will stub some or all methods.
-     * @param stubMethods  list of method signatures to always stub out
-     * @param deleteReturns list of types that trigger the deletion of methods returning them.
-     * @param className The name of the class being modified
-     * @param cv The parent class writer visitor
-     * @param stubNativesOnly True if only native methods should be stubbed. False if all
-     *                        methods should be stubbed.
-     */
-    public TransformClassAdapter(Log logger, Set<String> stubMethods,
-            Set<String> deleteReturns, String className, ClassVisitor cv,
-            boolean stubNativesOnly) {
-        super(Main.ASM_VERSION, cv);
-        mLog = logger;
-        mStubMethods = stubMethods;
-        mClassName = className;
-        mStubAll = !stubNativesOnly;
-        mIsInterface = false;
-        mDeleteReturns = deleteReturns;
-    }
-
-    /* Visits the class header. */
-    @Override
-    public void visit(int version, int access, String name,
-            String signature, String superName, String[] interfaces) {
-
-        // This class might be being renamed.
-        name = mClassName;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    /* Visits the header of an inner class. */
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-        // note: leave abstract classes as such
-        // don't try to implement stub for interfaces
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    /* Visits a method. */
-    @Override
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-
-        if (mDeleteReturns != null) {
-            Type t = Type.getReturnType(desc);
-            if (t.getSort() == Type.OBJECT) {
-                String returnType = t.getInternalName();
-                if (returnType != null) {
-                    if (mDeleteReturns.contains(returnType)) {
-                        return null;
-                    }
-                }
-            }
-        }
-
-        String methodSignature = mClassName.replace('/', '.') + "#" + name;
-
-        // remove final
-        access = access & ~Opcodes.ACC_FINAL;
-
-        // stub this method if they are all to be stubbed or if it is a native method
-        // and don't try to stub interfaces nor abstract non-native methods.
-        if (!mIsInterface &&
-            ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) &&
-            (mStubAll ||
-             (access & Opcodes.ACC_NATIVE) != 0) ||
-             mStubMethods.contains(methodSignature)) {
-
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-
-            // remove abstract, final and native
-            access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
-
-            String invokeSignature = methodSignature + desc;
-            mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
-
-            MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
-            return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
-                    isStatic, isNative);
-
-        } else {
-            mLog.debug("  Keep: %s %s", name, desc);
-            return super.visitMethod(access, name, desc, signature, exceptions);
-        }
-    }
-
-    /**
-     * Extracts the return {@link Type} of this descriptor.
-     */
-    Type returnType(String desc) {
-        if (desc != null) {
-            try {
-                return Type.getReturnType(desc);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // ignore, not a valid type.
-            }
-        }
-        return null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
deleted file mode 100644
index 7d6c4ec..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/AutoCloseable.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-/**
- * Defines the same interface as the java.lang.AutoCloseable which was added in
- * Java 7. This hack makes it possible to run the Android code which uses Java 7
- * features (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/AutoCloseable.java
- */
-public interface AutoCloseable {
-    /**
-     * Closes the object and release any system resources it holds.
-     */
-    void close() throws Exception;
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
deleted file mode 100644
index f73b06b..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Charsets.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.nio.charset.Charsets which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. An implementation of the native methods in the original
- * class has been added.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/nio/charset/Charsets
- */
-public final class Charsets {
-    /**
-     * A cheap and type-safe constant for the ISO-8859-1 Charset.
-     */
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
-    /**
-     * A cheap and type-safe constant for the US-ASCII Charset.
-     */
-    public static final Charset US_ASCII = Charset.forName("US-ASCII");
-
-    /**
-     * A cheap and type-safe constant for the UTF-8 Charset.
-     */
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in US-ASCII. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toAsciiBytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return US_ASCII.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in ISO-8859-1. Unrepresentable characters are replaced by (byte) '?'.
-     */
-    public static byte[] toIsoLatin1Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return ISO_8859_1.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-8. All characters are representable in UTF-8.
-     */
-    public static byte[] toUtf8Bytes(char[] chars, int offset, int length) {
-        CharBuffer cb = CharBuffer.allocate(length);
-        cb.put(chars, offset, length);
-        return UTF_8.encode(cb).array();
-    }
-
-    /**
-     * Returns a new byte array containing the bytes corresponding to the given characters,
-     * encoded in UTF-16BE. All characters are representable in UTF-16BE.
-     */
-    public static byte[] toBigEndianUtf16Bytes(char[] chars, int offset, int length) {
-        byte[] result = new byte[length * 2];
-        int end = offset + length;
-        int resultIndex = 0;
-        for (int i = offset; i < end; ++i) {
-            char ch = chars[i];
-            result[resultIndex++] = (byte) (ch >> 8);
-            result[resultIndex++] = (byte) ch;
-        }
-        return result;
-    }
-
-    /**
-     * Decodes the given US-ASCII bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     char ch = (char) (data[start++] & 0xff);
-     *     value[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-     * }
-     */
-    public static void asciiBytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        final char REPLACEMENT_CHAR = (char)0xffd;
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            char ch = (char) (bytes[start++] & 0xff);
-            chars[i] = (ch <= 0x7f) ? ch : REPLACEMENT_CHAR;
-        }
-    }
-
-    /**
-     * Decodes the given ISO-8859-1 bytes into the given char[]. Equivalent to but faster than:
-     *
-     * for (int i = 0; i < count; ++i) {
-     *     value[i] = (char) (data[start++] & 0xff);
-     * }
-     */
-    public static void isoLatin1BytesToChars(byte[] bytes, int offset, int length, char[] chars) {
-        if (bytes == null || chars == null) {
-            return;
-        }
-        int start = offset;
-        for (int i = 0; i < length; ++i) {
-            chars[i] = (char) (bytes[start++] & 0xff);
-        }
-    }
-
-    private Charsets() {
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
deleted file mode 100644
index e6dd00a..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/IntegralToString.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-/**
- * Defines the same class as the java.lang.IntegralToString which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it. Since it's no longer in java.lang, access to package
- * private methods and classes has been replaced by the closes matching public
- * implementation.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java
- */
-public final class IntegralToString {
-    /**
-     * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid
-     * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder
-     * because it's almost as expensive to work out the exact length of the result as it is to
-     * do the formatting. We could try being conservative and "delete"-ing the unused space
-     * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share
-     * the code.)
-     */
-    private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
-        @Override protected char[] initialValue() {
-            return new char[20]; // Maximum length of a base-10 long.
-        }
-    };
-
-    /**
-     * These tables are used to special-case toString computation for
-     * small values.  This serves three purposes: it reduces memory usage;
-     * it increases performance for small values; and it decreases the
-     * number of comparisons required to do the length computation.
-     * Elements of this table are lazily initialized on first use.
-     * No locking is necessary, i.e., we use the non-volatile, racy
-     * single-check idiom.
-     */
-    private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100];
-    private static final String[] SMALL_NEGATIVE_VALUES = new String[100];
-
-    /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] TENS = {
-        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
-        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
-        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
-        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
-        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
-        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
-        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
-        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
-        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
-        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
-    };
-
-    /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
-    private static final char[] ONES = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    };
-
-    /**
-     * Table for MOD / DIV 10 computation described in Section 10-21
-     * of Hank Warren's "Hacker's Delight" online addendum.
-     * http://www.hackersdelight.org/divcMore.pdf
-     */
-    private static final char[] MOD_10_TABLE = {
-        0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0
-    };
-
-    /**
-     * The digits for every supported radix.
-     */
-    private static final char[] DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
-        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-        'u', 'v', 'w', 'x', 'y', 'z'
-    };
-
-    private static final char[] UPPER_CASE_DIGITS = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-        'U', 'V', 'W', 'X', 'Y', 'Z'
-    };
-
-    private IntegralToString() {
-    }
-
-    /**
-     * Equivalent to Integer.toString(i, radix).
-     */
-    public static String intToString(int i, int radix) {
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return intToString(i);
-        }
-
-        /*
-         * If i is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (i < 0) {
-            negative = true;
-        } else {
-            i = -i;
-        }
-
-        int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            int q = i / radix;
-            buf[--cursor] = DIGITS[radix * q - i];
-            i = q;
-        } while (i != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Integer.toString(i).
-     */
-    public static String intToString(int i) {
-        return convertInt(null, i);
-    }
-
-    /**
-     * Equivalent to sb.append(Integer.toString(i)).
-     */
-    public static void appendInt(StringBuilder sb, int i) {
-        convertInt(sb, i);
-    }
-
-    /**
-     * Returns the string representation of i and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of i to sb if sb is non-null.
-     */
-    private static String convertInt(StringBuilder sb, int i) {
-        boolean negative = false;
-        String quickResult = null;
-        if (i < 0) {
-            negative = true;
-            i = -i;
-            if (i < 100) {
-                if (i < 0) {
-                    // If -n is still negative, n is Integer.MIN_VALUE
-                    quickResult = "-2147483648";
-                } else {
-                    quickResult = SMALL_NEGATIVE_VALUES[i];
-                    if (quickResult == null) {
-                        SMALL_NEGATIVE_VALUES[i] = quickResult =
-                                i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
-                    }
-                }
-            }
-        } else {
-            if (i < 100) {
-                quickResult = SMALL_NONNEGATIVE_VALUES[i];
-                if (quickResult == null) {
-                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
-                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
-                }
-            }
-        }
-        if (quickResult != null) {
-            if (sb != null) {
-                sb.append(quickResult);
-                return null;
-            }
-            return quickResult;
-        }
-
-        int bufLen = 11; // Max number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-        int cursor = bufLen;
-
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while (i >= (1 << 16)) {
-            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
-            int q = (int) ((0x51EB851FL * i) >>> 37);
-            int r = i - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            i = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (i != 0) {
-            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * i) >>> 19;
-            int r = i - 10*q;
-            buf[--cursor] = DIGITS[r];
-            i = q;
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Equivalent to Long.toString(v, radix).
-     */
-    public static String longToString(long v, int radix) {
-        int i = (int) v;
-        if (i == v) {
-            return intToString(i, radix);
-        }
-
-        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-            radix = 10;
-        }
-        if (radix == 10) {
-            return longToString(v);
-        }
-
-        /*
-         * If v is positive, negate it. This is the opposite of what one might
-         * expect. It is necessary because the range of the negative values is
-         * strictly larger than that of the positive values: there is no
-         * positive value corresponding to Integer.MIN_VALUE.
-         */
-        boolean negative = false;
-        if (v < 0) {
-            negative = true;
-        } else {
-            v = -v;
-        }
-
-        int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            long q = v / radix;
-            buf[--cursor] = DIGITS[(int) (radix * q - v)];
-            v = q;
-        } while (v != 0);
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    /**
-     * Equivalent to Long.toString(l).
-     */
-    public static String longToString(long l) {
-        return convertLong(null, l);
-    }
-
-    /**
-     * Equivalent to sb.append(Long.toString(l)).
-     */
-    public static void appendLong(StringBuilder sb, long l) {
-        convertLong(sb, l);
-    }
-
-    /**
-     * Returns the string representation of n and leaves sb alone if sb is null.
-     * Returns null and appends the string representation of n to sb if sb is non-null.
-     */
-    private static String convertLong(StringBuilder sb, long n) {
-        int i = (int) n;
-        if (i == n) {
-            return convertInt(sb, i);
-        }
-
-        boolean negative = (n < 0);
-        if (negative) {
-            n = -n;
-            if (n < 0) {
-                // If -n is still negative, n is Long.MIN_VALUE
-                String quickResult = "-9223372036854775808";
-                if (sb != null) {
-                    sb.append(quickResult);
-                    return null;
-                }
-                return quickResult;
-            }
-        }
-
-        int bufLen = 20; // Maximum number of chars in result
-        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
-
-        int low = (int) (n % 1000000000); // Extract low-order 9 digits
-        int cursor = intIntoCharArray(buf, bufLen, low);
-
-        // Zero-pad Low order part to 9 digits
-        while (cursor != (bufLen - 9)) {
-            buf[--cursor] = '0';
-        }
-
-        /*
-         * The remaining digits are (n - low) / 1,000,000,000.  This
-         * "exact division" is done as per the online addendum to Hank Warren's
-         * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
-         */
-        n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;
-
-        /*
-         * If the remaining digits fit in an int, emit them using a
-         * single call to intIntoCharArray. Otherwise, strip off the
-         * low-order digit, put it in buf, and then call intIntoCharArray
-         * on the remaining digits (which now fit in an int).
-         */
-        if ((n & (-1L << 32)) == 0) {
-            cursor = intIntoCharArray(buf, cursor, (int) n);
-        } else {
-            /*
-             * Set midDigit to n % 10
-             */
-            int lo32 = (int) n;
-            int hi32 = (int) (n >>> 32);
-
-            // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
-            int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];
-
-            // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
-            midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
-            if (midDigit < 0) {
-                midDigit += 10;
-            }
-            buf[--cursor] = DIGITS[midDigit];
-
-            // Exact division as per Warren 10-20
-            int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
-            cursor = intIntoCharArray(buf, cursor, rest);
-        }
-
-        if (negative) {
-            buf[--cursor] = '-';
-        }
-        if (sb != null) {
-            sb.append(buf, cursor, bufLen - cursor);
-            return null;
-        } else {
-            return new String(buf, cursor, bufLen - cursor);
-        }
-    }
-
-    /**
-     * Inserts the unsigned decimal integer represented by n into the specified
-     * character array starting at position cursor.  Returns the index after
-     * the last character inserted (i.e., the value to pass in as cursor the
-     * next time this method is called). Note that n is interpreted as a large
-     * positive integer (not a negative integer) if its sign bit is set.
-     */
-    private static int intIntoCharArray(char[] buf, int cursor, int n) {
-        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
-        while ((n & 0xffff0000) != 0) {
-            /*
-             * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
-             * This computation is slightly different from the corresponding
-             * computation in intToString: the shifts before and after
-             * multiply can't be combined, as that would yield the wrong result
-             * if n's sign bit were set.
-             */
-            int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
-            int r = n - 100*q;
-            buf[--cursor] = ONES[r];
-            buf[--cursor] = TENS[r];
-            n = q;
-        }
-
-        // Calculate remaining digits one-at-a-time for performance
-        while (n != 0) {
-            // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
-            int q = (0xCCCD * n) >>> 19;
-            int r = n - 10*q;
-            buf[--cursor] = DIGITS[r];
-            n = q;
-        }
-        return cursor;
-    }
-
-    public static String intToBinaryString(int i) {
-        int bufLen = 32;  // Max number of binary digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 1];
-        }  while ((i >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToBinaryString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToBinaryString(i);
-        }
-
-        int bufLen = 64;  // Max number of binary digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 1];
-        }  while ((v >>>= 1) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        sb.append(digits[(b >> 4) & 0xf]);
-        sb.append(digits[b & 0xf]);
-        return sb;
-    }
-
-    public static String byteToHexString(byte b, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[2]; // We always want two digits.
-        buf[0] = digits[(b >> 4) & 0xf];
-        buf[1] = digits[b & 0xf];
-        return new String(buf, 0, 2);
-    }
-
-    public static String bytesToHexString(byte[] bytes, boolean upperCase) {
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        char[] buf = new char[bytes.length * 2];
-        int c = 0;
-        for (byte b : bytes) {
-            buf[c++] = digits[(b >> 4) & 0xf];
-            buf[c++] = digits[b & 0xf];
-        }
-        return new String(buf);
-    }
-
-    public static String intToHexString(int i, boolean upperCase, int minWidth) {
-        int bufLen = 8;  // Max number of hex digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
-        do {
-            buf[--cursor] = digits[i & 0xf];
-        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToHexString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToHexString(i, false, 0);
-        }
-
-        int bufLen = 16;  // Max number of hex digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 0xF];
-        } while ((v >>>= 4) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String intToOctalString(int i) {
-        int bufLen = 11;  // Max number of octal digits in an int
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[i & 7];
-        } while ((i >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    public static String longToOctalString(long v) {
-        int i = (int) v;
-        if (v >= 0 && i == v) {
-            return intToOctalString(i);
-        }
-        int bufLen = 22;  // Max number of octal digits in a long
-        char[] buf = new char[bufLen];
-        int cursor = bufLen;
-
-        do {
-            buf[--cursor] = DIGITS[((int) v) & 7];
-        } while ((v >>>= 3) != 0);
-
-        return new String(buf, cursor, bufLen - cursor);
-    }
-
-    private static String stringOf(char... args) {
-        return new String(args, 0, args.length);
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
deleted file mode 100644
index 59cc75f..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/LinkedHashMap_Delegate.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Provides alternate implementation to java.util.LinkedHashMap#eldest(), which is present as a
- * non-public method in the Android VM, but not present on the host VM. This is injected in the
- * layoutlib using {@link ReplaceMethodCallsAdapter}.
- */
-public class LinkedHashMap_Delegate {
-    public static <K,V> Map.Entry<K,V> eldest(LinkedHashMap<K,V> map) {
-        Iterator<Entry<K, V>> iterator = map.entrySet().iterator();
-        return iterator.hasNext() ? iterator.next() : null;
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
deleted file mode 100644
index eb1ef72..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/Objects.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-/**
- * Defines the same class as the java.util.Objects which is added in Java 7.
- * This hack makes it possible to run the Android code which uses Java 7 features
- * (API 18 and beyond) to run on Java 6.
- * <p/>
- * Extracted from API level 19, file:
- * platform/libcore/luni/src/main/java/java/util/Objects.java
- */
-public final class Objects {
-  private Objects() {}
-
-  /**
-   * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
-   * That is, this makes {@code c} null-safe.
-   */
-  public static <T> int compare(T a, T b, Comparator<? super T> c) {
-    if (a == b) {
-      return 0;
-    }
-    return c.compare(a, b);
-  }
-
-  /**
-   * Returns true if both arguments are null,
-   * the result of {@link Arrays#equals} if both arguments are primitive arrays,
-   * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
-   * and the result of {@link #equals} otherwise.
-   */
-  public static boolean deepEquals(Object a, Object b) {
-    if (a == null || b == null) {
-      return a == b;
-    } else if (a instanceof Object[] && b instanceof Object[]) {
-      return Arrays.deepEquals((Object[]) a, (Object[]) b);
-    } else if (a instanceof boolean[] && b instanceof boolean[]) {
-      return Arrays.equals((boolean[]) a, (boolean[]) b);
-    } else if (a instanceof byte[] && b instanceof byte[]) {
-      return Arrays.equals((byte[]) a, (byte[]) b);
-    } else if (a instanceof char[] && b instanceof char[]) {
-      return Arrays.equals((char[]) a, (char[]) b);
-    } else if (a instanceof double[] && b instanceof double[]) {
-      return Arrays.equals((double[]) a, (double[]) b);
-    } else if (a instanceof float[] && b instanceof float[]) {
-      return Arrays.equals((float[]) a, (float[]) b);
-    } else if (a instanceof int[] && b instanceof int[]) {
-      return Arrays.equals((int[]) a, (int[]) b);
-    } else if (a instanceof long[] && b instanceof long[]) {
-      return Arrays.equals((long[]) a, (long[]) b);
-    } else if (a instanceof short[] && b instanceof short[]) {
-      return Arrays.equals((short[]) a, (short[]) b);
-    }
-    return a.equals(b);
-  }
-
-  /**
-   * Null-safe equivalent of {@code a.equals(b)}.
-   */
-  public static boolean equals(Object a, Object b) {
-    return (a == null) ? (b == null) : a.equals(b);
-  }
-
-  /**
-   * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
-   * This can be used to compute a hash code for an object's fields as follows:
-   * {@code Objects.hash(a, b, c)}.
-   */
-  public static int hash(Object... values) {
-    return Arrays.hashCode(values);
-  }
-
-  /**
-   * Returns 0 for null or {@code o.hashCode()}.
-   */
-  public static int hashCode(Object o) {
-    return (o == null) ? 0 : o.hashCode();
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}.
-   */
-  public static <T> T requireNonNull(T o) {
-    if (o == null) {
-      throw new NullPointerException();
-    }
-    return o;
-  }
-
-  /**
-   * Returns {@code o} if non-null, or throws {@code NullPointerException}
-   * with the given detail message.
-   */
-  public static <T> T requireNonNull(T o, String message) {
-    if (o == null) {
-      throw new NullPointerException(message);
-    }
-    return o;
-  }
-
-  /**
-   * Returns "null" for null or {@code o.toString()}.
-   */
-  public static String toString(Object o) {
-    return (o == null) ? "null" : o.toString();
-  }
-
-  /**
-   * Returns {@code nullString} for null or {@code o.toString()}.
-   */
-  public static String toString(Object o, String nullString) {
-    return (o == null) ? nullString : o.toString();
-  }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
deleted file mode 100644
index be93744..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/System_Delegate.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provides dummy implementation of methods that don't exist on the host VM.
- * This also providers a time control that allows to set a specific system time.
- *
- * @see ReplaceMethodCallsAdapter
- */
-@SuppressWarnings("unused")
-public class System_Delegate {
-    // Current system time
-    private static AtomicLong mNanosTime = new AtomicLong(System.nanoTime());
-    // Time that the system booted up in nanos
-    private static AtomicLong mBootNanosTime = new AtomicLong(System.nanoTime());
-
-    public static void log(String message) {
-        // ignore.
-    }
-
-    public static void log(String message, Throwable th) {
-        // ignore.
-    }
-
-    public static void setNanosTime(long nanos) {
-        mNanosTime.set(nanos);
-    }
-
-    public static void setBootTimeNanos(long nanos) {
-        mBootNanosTime.set(nanos);
-    }
-
-    public static long nanoTime() {
-        return mNanosTime.get();
-    }
-
-    public static long currentTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mNanosTime.get());
-    }
-
-    public static long bootTime() {
-        return mBootNanosTime.get();
-    }
-
-    public static long bootTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mBootNanosTime.get());
-    }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
deleted file mode 100644
index 0e09080..0000000
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/java/UnsafeByteSequence.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.java;
-
-import java.nio.charset.Charset;
-
-/**
- * Defines the same class as the java.lang.UnsafeByteSequence which was added in
- * Dalvik VM. This hack, provides a replacement for that class which can't be
- * loaded in the standard JVM since it's in the java package and standard JVM
- * doesn't have it.
- * <p/>
- * Extracted from API level 18, file:
- * platform/libcore/luni/src/main/java/java/lang/UnsafeByteSequence.java
- */
-public class UnsafeByteSequence {
-    private byte[] bytes;
-    private int count;
-
-    public UnsafeByteSequence(int initialCapacity) {
-        this.bytes = new byte[initialCapacity];
-    }
-
-    public int size() {
-        return count;
-    }
-
-    /**
-     * Moves the write pointer back to the beginning of the sequence,
-     * but without resizing or reallocating the buffer.
-     */
-    public void rewind() {
-        count = 0;
-    }
-
-    public void write(byte[] buffer, int offset, int length) {
-        if (count + length >= bytes.length) {
-            byte[] newBytes = new byte[(count + length) * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        System.arraycopy(buffer, offset, bytes, count, length);
-        count += length;
-    }
-
-    public void write(int b) {
-        if (count == bytes.length) {
-            byte[] newBytes = new byte[count * 2];
-            System.arraycopy(bytes, 0, newBytes, 0, count);
-            bytes = newBytes;
-        }
-        bytes[count++] = (byte) b;
-    }
-
-    public byte[] toByteArray() {
-        if (count == bytes.length) {
-            return bytes;
-        }
-        byte[] result = new byte[count];
-        System.arraycopy(bytes, 0, result, 0, count);
-        return result;
-    }
-
-    public String toString(Charset cs) {
-        return new String(bytes, 0, count, cs);
-    }
-}
diff --git a/tools/layoutlib/create/tests/Android.mk b/tools/layoutlib/create/tests/Android.mk
deleted file mode 100644
index 488d7d6..0000000
--- a/tools/layoutlib/create/tests/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, com)
-
-LOCAL_JAVA_RESOURCE_DIRS := data mock_data
-
-LOCAL_MODULE := layoutlib-create-tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := layoutlib_create junit-host
-LOCAL_STATIC_JAVA_LIBRARIES := asm-5.2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Copy the jar to DIST_DIR for sdk builds
-$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE))
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
deleted file mode 100644
index f86917a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Unit tests for some methods of {@link AsmAnalyzer}.
- */
-public class AsmAnalyzerTest {
-
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private AsmAnalyzer mAa;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        Set<String> excludeClasses = Collections.singleton("java.lang.JavaClass");
-
-        String[] includeFiles = new String[]{"mock_android/data/data*"};
-        mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */,
-                null /* includeGlobs */, excludeClasses, includeFiles);
-    }
-
-    @Test
-    public void testParseZip() throws IOException {
-
-        Map<String, ClassReader> map = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, map, filesFound);
-
-        assertArrayEquals(new String[] {
-                "java.lang.JavaClass",
-                "mock_android.dummy.InnerTest",
-                "mock_android.dummy.InnerTest$DerivingClass",
-                "mock_android.dummy.InnerTest$MyGenerics1",
-                "mock_android.dummy.InnerTest$MyIntEnum",
-                "mock_android.dummy.InnerTest$MyStaticInnerClass",
-                "mock_android.dummy.InnerTest$NotStaticInner1",
-                "mock_android.dummy.InnerTest$NotStaticInner2",
-                "mock_android.util.EmptyArray",
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.LinearLayout$LayoutParams",
-                "mock_android.widget.TableLayout",
-                "mock_android.widget.TableLayout$LayoutParams"
-            },
-            map.keySet().toArray());
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-            filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testFindClass() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
-                zipClasses, found);
-
-        assertNotNull(cr);
-        assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName());
-        assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" },
-                found.keySet().toArray());
-        assertArrayEquals(new ClassReader[] { cr }, found.values().toArray());
-    }
-
-    @Test
-    public void testFindGlobs() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        // this matches classes, a package match returns nothing
-        found.clear();
-        mAa.findGlobs("mock_android.view", zipClasses, found);
-
-        assertArrayEquals(new String[] { },
-            found.keySet().toArray());
-
-        // a complex glob search. * is a search pattern that matches names, not dots
-        mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // a complex glob search. ** is a search pattern that matches names including dots
-        mAa.findGlobs("mock_android.**Group*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        // matches a single class
-        found.clear();
-        mAa.findGlobs("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View"
-            },
-            found.keySet().toArray());
-
-        // matches everyting inside the given package but not sub-packages
-        found.clear();
-        mAa.findGlobs("mock_android.view.*", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams"
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testFindClassesDerivingFrom() throws LogAbortException, IOException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> found = new TreeMap<>();
-
-        mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found);
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout",
-                "mock_android.widget.TableLayout",
-            },
-            found.keySet().toArray());
-
-        for (String key : found.keySet()) {
-            ClassReader value = found.get(key);
-            assertNotNull("No value for " + key, value);
-            assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
-        }
-    }
-
-    @Test
-    public void testDependencyVisitor() throws IOException, LogAbortException {
-
-        Map<String, ClassReader> zipClasses = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-
-        mAa.parseZip(mOsJarPath, zipClasses, filesFound);
-        TreeMap<String, ClassReader> keep = new TreeMap<>();
-        TreeMap<String, ClassReader> new_keep = new TreeMap<>();
-        TreeMap<String, ClassReader> in_deps = new TreeMap<>();
-        TreeMap<String, ClassReader> out_deps = new TreeMap<>();
-
-        ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep);
-        DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);
-
-        // get first level dependencies
-        cr.accept(visitor, 0 /* flags */);
-
-        assertArrayEquals(new String[] {
-                "mock_android.util.EmptyArray",
-                "mock_android.view.ViewGroup",
-                "mock_android.widget.LinearLayout$LayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get second level dependencies
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-
-        assertArrayEquals(new String[] {
-                "mock_android.view.View",
-                "mock_android.view.ViewGroup$LayoutParams",
-                "mock_android.view.ViewGroup$MarginLayoutParams",
-            },
-            out_deps.keySet().toArray());
-
-        in_deps.putAll(out_deps);
-        out_deps.clear();
-
-        // get third level dependencies (there are none)
-        for (ClassReader cr2 : in_deps.values()) {
-            cr2.accept(visitor, 0 /* flags */);
-        }
-        keep.putAll(new_keep);
-
-        assertArrayEquals(new String[] { }, out_deps.keySet().toArray());
-        assertArrayEquals(new String[] {
-                "mock_android.widget.LinearLayout",
-        }, keep.keySet().toArray());
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
deleted file mode 100644
index e718fb9..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Type;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for some methods of {@link AsmGenerator}.
- */
-public class AsmGeneratorTest {
-    private MockLog mLog;
-    private ArrayList<String> mOsJarPath;
-    private String mOsDestJar;
-    private File mTempFile;
-
-    // ASM internal name for the the class in java package that should be refactored.
-    private static final String JAVA_CLASS_NAME = "java/lang/JavaClass";
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-
-        mOsJarPath = new ArrayList<>();
-        //noinspection ConstantConditions
-        mOsJarPath.add(url.getFile());
-
-        mTempFile = File.createTempFile("mock", ".jar");
-        mOsDestJar = mTempFile.getAbsolutePath();
-        mTempFile.deleteOnExit();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mTempFile != null) {
-            //noinspection ResultOfMethodCallIgnored
-            mTempFile.delete();
-            mTempFile = null;
-        }
-    }
-
-    @Test
-    public void testClassRenaming() throws IOException, LogAbortException {
-
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                        "not.an.actual.ClassName", "anoter.fake.NewClassName",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet() /* excluded classes */,
-                new String[]{} /* include files */);
-        aa.analyze();
-        agen.generate();
-
-        Set<String> notRenamed = agen.getClassesNotRenamed();
-        assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
-
-    }
-
-    @Test
-    public void testJavaClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-             // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass",
-                };
-            }
-
-            @Override
-            public Set<String> getExcludedClasses() {
-                return Collections.singleton("java.lang.JavaClass");
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                    "**"
-                },
-                Collections.emptySet(),
-                new String[] {        /* include files */
-                    "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "com/android/tools/layoutlib/create/dataclass/JavaClass"));
-        assertFalse(cv.mVisitedClasses.contains(
-                JAVA_CLASS_NAME));
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[] {
-                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
-                };
-            }
-
-            @Override
-            public String[] getRefactoredClasses() {
-                // classes to refactor (so that we can replace them)
-                return new String[] {
-                        "mock_android.view.View", "mock_android.view._Original_View",
-                };
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                Collections.emptySet(),
-                new String[] {});
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        parseZip(mOsDestJar, output, new TreeMap<>());
-        RecordingClassVisitor cv = new RecordingClassVisitor();
-        for (ClassReader cr: output.values()) {
-            cr.accept(cv, 0);
-        }
-        assertTrue(cv.mVisitedClasses.contains(
-                "mock_android/view/_Original_View"));
-        assertFalse(cv.mVisitedClasses.contains(
-                "mock_android/view/View"));
-    }
-
-    @Test
-    public void testClassExclusion() throws IOException, LogAbortException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Set<String> getExcludedClasses() {
-                Set<String> set = new HashSet<>(2);
-                set.add("mock_android.dummy.InnerTest");
-                set.add("java.lang.JavaClass");
-                return set;
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        Set<String> excludedClasses = ci.getExcludedClasses();
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                excludedClasses,
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        for (String s : output.keySet()) {
-            assertFalse(excludedClasses.contains(s));
-        }
-        assertArrayEquals(new String[] {"mock_android/data/dataFile"},
-                filesFound.keySet().toArray());
-    }
-
-    @Test
-    public void testMethodInjection() throws IOException, LogAbortException,
-            ClassNotFoundException, IllegalAccessException, InstantiationException,
-            NoSuchMethodException, InvocationTargetException {
-        ICreateInfo ci = new CreateInfoAdapter() {
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.singletonMap("mock_android.util.EmptyArray",
-                        InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
-            }
-        };
-
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
-        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
-                null,                 // derived from
-                new String[] {        // include classes
-                        "**"
-                },
-                ci.getExcludedClasses(),
-                new String[] {        /* include files */
-                        "mock_android/data/data*"
-                });
-        aa.analyze();
-        agen.generate();
-        Map<String, ClassReader> output = new TreeMap<>();
-        Map<String, InputStream> filesFound = new TreeMap<>();
-        parseZip(mOsDestJar, output, filesFound);
-        final String modifiedClass = "mock_android.util.EmptyArray";
-        final String modifiedClassPath = modifiedClass.replace('.', '/').concat(".class");
-        ZipFile zipFile = new ZipFile(mOsDestJar);
-        ZipEntry entry = zipFile.getEntry(modifiedClassPath);
-        assertNotNull(entry);
-        final byte[] bytes;
-        try (InputStream inputStream = zipFile.getInputStream(entry)) {
-            bytes = getByteArray(inputStream);
-        }
-        ClassLoader classLoader = new ClassLoader(getClass().getClassLoader()) {
-            @Override
-            protected Class<?> findClass(String name) throws ClassNotFoundException {
-                if (name.equals(modifiedClass)) {
-                    return defineClass(null, bytes, 0, bytes.length);
-                }
-                throw new ClassNotFoundException(name + " not found.");
-            }
-        };
-        Class<?> emptyArrayClass = classLoader.loadClass(modifiedClass);
-        Object emptyArrayInstance = emptyArrayClass.newInstance();
-        Method method = emptyArrayClass.getMethod("getFrameworkClassLoader");
-        Object cl = method.invoke(emptyArrayInstance);
-        assertEquals(classLoader, cl);
-    }
-
-    private static byte[] getByteArray(InputStream stream) throws IOException {
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int read;
-        while ((read = stream.read(buffer, 0, buffer.length)) > -1) {
-            bos.write(buffer, 0, read);
-        }
-        return bos.toByteArray();
-    }
-
-    private void parseZip(String jarPath,
-            Map<String, ClassReader> classes,
-            Map<String, InputStream> filesFound) throws IOException {
-
-            ZipFile zip = new ZipFile(jarPath);
-            Enumeration<? extends ZipEntry> entries = zip.entries();
-            ZipEntry entry;
-            while (entries.hasMoreElements()) {
-                entry = entries.nextElement();
-                if (entry.getName().endsWith(".class")) {
-                    ClassReader cr = new ClassReader(zip.getInputStream(entry));
-                    String className = classReaderToClassName(cr);
-                    classes.put(className, cr);
-                } else {
-                    filesFound.put(entry.getName(), zip.getInputStream(entry));
-                }
-            }
-
-    }
-
-    private String classReaderToClassName(ClassReader classReader) {
-        if (classReader == null) {
-            return null;
-        } else {
-            return classReader.getClassName().replace('/', '.');
-        }
-    }
-
-    /**
-     * {@link ClassVisitor} that records every class that sees.
-     */
-    private static class RecordingClassVisitor extends ClassVisitor {
-        private Set<String> mVisitedClasses = new HashSet<>();
-
-        private RecordingClassVisitor() {
-            super(Main.ASM_VERSION);
-        }
-
-        private void addClass(String className) {
-            if (className == null) {
-                return;
-            }
-
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                // For inner classes, add also the base class
-                mVisitedClasses.add(className.substring(0, pos));
-            }
-            mVisitedClasses.add(className);
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            addClass(superName);
-            Arrays.stream(interfaces).forEach(this::addClass);
-        }
-
-        private void processType(Type type) {
-            switch (type.getSort()) {
-                case Type.OBJECT:
-                    addClass(type.getInternalName());
-                    break;
-                case Type.ARRAY:
-                    addClass(type.getElementType().getInternalName());
-                    break;
-                case Type.METHOD:
-                    processType(type.getReturnType());
-                    Arrays.stream(type.getArgumentTypes()).forEach(this::processType);
-                    break;
-            }
-        }
-
-        @Override
-        public FieldVisitor visitField(int access, String name, String desc, String signature,
-                Object value) {
-            processType(Type.getType(desc));
-            return super.visitField(access, name, desc, signature, value);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-            return new MethodVisitor(Main.ASM_VERSION, mv) {
-
-                @Override
-                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitFieldInsn(opcode, owner, name, desc);
-                }
-
-                @Override
-                public void visitLdcInsn(Object cst) {
-                    if (cst instanceof Type) {
-                        processType((Type) cst);
-                    }
-                    super.visitLdcInsn(cst);
-                }
-
-                @Override
-                public void visitTypeInsn(int opcode, String type) {
-                    addClass(type);
-                    super.visitTypeInsn(opcode, type);
-                }
-
-                @Override
-                public void visitMethodInsn(int opcode, String owner, String name, String desc,
-                        boolean itf) {
-                    addClass(owner);
-                    processType(Type.getType(desc));
-                    super.visitMethodInsn(opcode, owner, name, desc, itf);
-                }
-
-            };
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
deleted file mode 100644
index 0cdcdc0..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-
-/**
- * Tests {@link ClassHasNativeVisitor}.
- */
-public class ClassHasNativeVisitorTest {
-
-    @Test
-    public void testHasNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-                this.getClass().getCanonicalName() + "$" + ClassWithNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
-        assertTrue(cv.hasNativeMethods());
-    }
-
-    @Test
-    public void testHasNoNative() throws IOException {
-        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
-        String className =
-            this.getClass().getCanonicalName() + "$" + ClassWithoutNative.class.getSimpleName();
-        ClassReader cr = new ClassReader(className);
-
-        cr.accept(cv, 0 /* flags */);
-        assertArrayEquals(new String[0], cv.getMethodsFound());
-        assertFalse(cv.hasNativeMethods());
-    }
-
-    //-------
-
-    /**
-     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
-     */
-    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
-        private ArrayList<String> mMethodsFound = new ArrayList<>();
-
-        public String[] getMethodsFound() {
-            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
-        }
-
-        @Override
-        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
-            if (hasNativeMethods) {
-                mMethodsFound.add(methodName);
-            }
-            super.setHasNativeMethods(hasNativeMethods, methodName);
-        }
-    }
-
-    /**
-     * Dummy test class with a native method.
-     */
-    public static class ClassWithNative {
-        public ClassWithNative() {
-        }
-
-        public void callTheNativeMethod() {
-            native_method();
-        }
-
-        private native void native_method();
-    }
-
-    /**
-     * Dummy test class with no native method.
-     */
-    public static class ClassWithoutNative {
-        public ClassWithoutNative() {
-        }
-
-        public void someMethod() {
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
deleted file mode 100644
index ad7cb9a..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-class CreateInfoAdapter implements ICreateInfo {
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    @Override
-    public Class<?>[] getInjectedClasses() {
-        return new Class<?>[0];
-    }
-
-    @Override
-    public String[] getDelegateMethods() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDelegateClassNatives() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRenamedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getRefactoredClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getDeleteReturns() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getJavaPkgClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Set<String> getExcludedClasses() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public String[] getPromotedFields() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public String[] getPromotedClasses() {
-        return EMPTY_STRING_ARRAY;
-    }
-
-    @Override
-    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-        return Collections.emptyMap();
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
deleted file mode 100644
index afaa399..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.tools.layoutlib.create.dataclass.ClassWithNative;
-import com.android.tools.layoutlib.create.dataclass.OuterClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-public class DelegateClassAdapterTest {
-
-    private MockLog mLog;
-
-    private static final String NATIVE_CLASS_NAME = ClassWithNative.class.getName();
-    private static final String OUTER_CLASS_NAME = OuterClass.class.getName();
-    private static final String INNER_CLASS_NAME = InnerClass.class.getName();
-    private static final String STATIC_INNER_CLASS_NAME = StaticInnerClass.class.getName();
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-        mLog.setVerbose(true); // capture debug error too
-    }
-
-    /**
-     * Tests that a class not being modified still works.
-     */
-    @Test
-    public void testNoOp() throws Throwable {
-        // create an instance of the class that will be modified
-        // (load the class in a distinct class loader so that we can trash its definition later)
-        ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) { };
-        @SuppressWarnings("unchecked")
-        Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
-        ClassWithNative instance1 = clazz1.newInstance();
-        assertEquals(42, instance1.add(20, 22));
-        try {
-            instance1.callNativeInstance(10, 3.1415, new Object[0] );
-            fail("Test should have failed to invoke callTheNativeMethod [1]");
-        } catch (UnsatisfiedLinkError e) {
-            // This is expected to fail since the native method is not implemented.
-        }
-
-        // Now process it but tell the delegate to not modify any method
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it again
-
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                    try {
-                        callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
-                        fail("Test should have failed to invoke callTheNativeMethod [2]");
-                    } catch (InvocationTargetException e) {
-                        // This is expected to fail since the native method has NOT been
-                        // overridden here.
-                        assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
-                    }
-
-                    // Check that the native method does NOT have the new annotation
-                    Method[] m = clazz2.getDeclaredMethods();
-                    Method nativeInstanceMethod = null;
-                    for (Method method : m) {
-                        if ("native_instance".equals(method.getName())) {
-                            nativeInstanceMethod = method;
-                            break;
-                        }
-                    }
-                    assertNotNull(nativeInstanceMethod);
-                    assertTrue(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                    Annotation[] a = nativeInstanceMethod.getAnnotations();
-                    assertEquals(0, a.length);
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    /**
-     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
-     * so this should fail with an {@link UnsupportedOperationException}.
-     *
-     * Although not tested here, the message of the exception should contain the
-     * constructor signature.
-     */
-    @Test(expected=UnsupportedOperationException.class)
-    public void testConstructorsNotSupported() throws IOException {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("<init>");
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-    }
-
-    @Test
-    public void testDelegateNative() throws Throwable {
-        ClassWriter cw = new ClassWriter(0 /*flags*/);
-        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
-
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
-        DelegateClassAdapter cv = new DelegateClassAdapter(
-                mLog, cw, internalClassName, delegateMethods);
-
-        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
-        cr.accept(cv, 0 /* flags */);
-
-        // Load the generated class in a different class loader and try it
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
-                    Object i2 = clazz2.newInstance();
-                    assertNotNull(i2);
-
-                    // Use reflection to access inner methods
-                    assertEquals(42, callAdd(i2, 20, 22));
-
-                     Object[] objResult = new Object[] { null };
-                     int result = callCallNativeInstance(i2, 10, 3.1415, objResult);
-                     assertEquals((int)(10 + 3.1415), result);
-                     assertSame(i2, objResult[0]);
-
-                     // Check that the native method now has the new annotation and is not native
-                     Method[] m = clazz2.getDeclaredMethods();
-                     Method nativeInstanceMethod = null;
-                     for (Method method : m) {
-                         if ("native_instance".equals(method.getName())) {
-                             nativeInstanceMethod = method;
-                             break;
-                         }
-                     }
-                     assertNotNull(nativeInstanceMethod);
-                     assertFalse(Modifier.isNative(nativeInstanceMethod.getModifiers()));
-                     Annotation[] a = nativeInstanceMethod.getAnnotations();
-                     assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
-                }
-            };
-            cl2.add(NATIVE_CLASS_NAME, cw);
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-        delegateMethods.add("privateMethod");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // The original Outer.get returns 1+10+20,
-                    // but the delegate makes it return 4+10+20
-                    assertEquals(4+10+20, callGet(o2, 10, 20));
-                    assertEquals(1+10+20, callGet_Original(o2, 10, 20));
-
-                    // The original Outer has a private method,
-                    // so by default we can't access it.
-                    boolean gotIllegalAccessException = false;
-                    try {
-                         callMethod(o2, "privateMethod", false /*makePublic*/);
-                    } catch(IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // The private method from original Outer has been
-                    // delegated. The delegate generated should have the
-                    // same access.
-                    gotIllegalAccessException = false;
-                    try {
-                        assertEquals("outerPrivateMethod",
-                                callMethod(o2, "privateMethod_Original", false /*makePublic*/));
-                    } catch (IllegalAccessException e) {
-                        gotIllegalAccessException = true;
-                    }
-                    assertTrue(gotIllegalAccessException);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
-                    Object i2 = innerCons.newInstance(o2);
-                    assertNotNull(i2);
-
-                    // The original Inner.get returns 3+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(3+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    @Test
-    public void testDelegateStaticInner() throws Throwable {
-        // We'll delegate the "get" method of both the inner and outer class.
-        HashSet<String> delegateMethods = new HashSet<>();
-        delegateMethods.add("get");
-
-        // Generate the delegate for the outer class.
-        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
-        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
-                mLog, cwOuter, outerClassName, delegateMethods);
-        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
-        cr.accept(cvOuter, 0 /* flags */);
-
-        // Generate the delegate for the static inner class.
-        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
-        String innerClassName = STATIC_INNER_CLASS_NAME.replace('.', '/');
-        DelegateClassAdapter cvInner = new DelegateClassAdapter(
-                mLog, cwInner, innerClassName, delegateMethods);
-        cr = new ClassReader(STATIC_INNER_CLASS_NAME);
-        cr.accept(cvInner, 0 /* flags */);
-
-        // Load the generated classes in a different class loader and try them
-        ClassLoader2 cl2 = null;
-        try {
-            cl2 = new ClassLoader2() {
-                @Override
-                public void testModifiedInstance() throws Exception {
-
-                    // Check the outer class
-                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
-                    Object o2 = outerClazz2.newInstance();
-                    assertNotNull(o2);
-
-                    // Check the inner class. Since it's not a static inner class, we need
-                    // to use the hidden constructor that takes the outer class as first parameter.
-                    Class<?> innerClazz2 = loadClass(STATIC_INNER_CLASS_NAME);
-                    Constructor<?> innerCons = innerClazz2.getConstructor();
-                    Object i2 = innerCons.newInstance();
-                    assertNotNull(i2);
-
-                    // The original StaticInner.get returns 100+10+20,
-                    // but the delegate makes it return 6+10+20
-                    assertEquals(6+10+20, callGet(i2, 10, 20));
-                    assertEquals(100+10+20, callGet_Original(i2, 10, 20));
-                }
-            };
-            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
-            cl2.add(STATIC_INNER_CLASS_NAME, cwInner.toByteArray());
-            cl2.testModifiedInstance();
-        } catch (Throwable t) {
-            throw dumpGeneratedClass(t, cl2);
-        }
-    }
-
-    //-------
-
-    /**
-     * A class loader than can define and instantiate our modified classes.
-     * <p/>
-     * The trick here is that this class loader will test our <em>modified</em> version
-     * of the classes, the one with the delegate calls.
-     * <p/>
-     * Trying to do so in the original class loader generates all sort of link issues because
-     * there are 2 different definitions of the same class name. This class loader will
-     * define and load the class when requested by name and provide helpers to access the
-     * instance methods via reflection.
-     */
-    private abstract class ClassLoader2 extends ClassLoader {
-
-        private final Map<String, byte[]> mClassDefs = new HashMap<>();
-
-        public ClassLoader2() {
-            super(null);
-        }
-
-        public ClassLoader2 add(String className, byte[] definition) {
-            mClassDefs.put(className, definition);
-            return this;
-        }
-
-        public ClassLoader2 add(String className, ClassWriter rewrittenClass) {
-            mClassDefs.put(className, rewrittenClass.toByteArray());
-            return this;
-        }
-
-        private Set<Entry<String, byte[]>> getByteCode() {
-            return mClassDefs.entrySet();
-        }
-
-        @SuppressWarnings("unused")
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            try {
-                return super.findClass(name);
-            } catch (ClassNotFoundException e) {
-
-                byte[] def = mClassDefs.get(name);
-                if (def != null) {
-                    // Load the modified ClassWithNative from its bytes representation.
-                    return defineClass(name, def, 0, def.length);
-                }
-
-                try {
-                    // Load everything else from the original definition into the new class loader.
-                    ClassReader cr = new ClassReader(name);
-                    ClassWriter cw = new ClassWriter(0);
-                    cr.accept(cw, 0);
-                    byte[] bytes = cw.toByteArray();
-                    return defineClass(name, bytes, 0, bytes.length);
-
-                } catch (IOException ioe) {
-                    throw new RuntimeException(ioe);
-                }
-            }
-        }
-
-        /**
-         * Accesses {@link OuterClass#get} or {@link InnerClass#get}via reflection.
-         */
-        public int callGet(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the "_Original" methods for {@link OuterClass#get}
-         * or {@link InnerClass#get}via reflection.
-         */
-        public int callGet_Original(Object instance, int a, long b) throws Exception {
-            Method m = instance.getClass().getMethod("get_Original",
-                    int.class, long.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses the any declared method that takes no parameter via reflection.
-         */
-        @SuppressWarnings("unchecked")
-        public <T> T callMethod(Object instance, String methodName, boolean makePublic) throws Exception {
-            Method m = instance.getClass().getDeclaredMethod(methodName, (Class<?>[])null);
-
-            boolean wasAccessible = m.isAccessible();
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(true);
-            }
-
-            Object result = m.invoke(instance, (Object[])null);
-
-            if (makePublic && !wasAccessible) {
-                m.setAccessible(false);
-            }
-
-            return (T) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#add(int, int)} via reflection.
-         */
-        public int callAdd(Object instance, int a, int b) throws Exception {
-            Method m = instance.getClass().getMethod("add",
-                    int.class, int.class);
-
-            Object result = m.invoke(instance, a, b);
-            return (Integer) result;
-        }
-
-        /**
-         * Accesses {@link ClassWithNative#callNativeInstance(int, double, Object[])}
-         * via reflection.
-         */
-        public int callCallNativeInstance(Object instance, int a, double d, Object[] o)
-                throws Exception {
-            Method m = instance.getClass().getMethod("callNativeInstance",
-                    int.class, double.class, Object[].class);
-
-            Object result = m.invoke(instance, a, d, o);
-            return (Integer) result;
-        }
-
-        public abstract void testModifiedInstance() throws Exception;
-    }
-
-    /**
-     * For debugging, it's useful to dump the content of the generated classes
-     * along with the exception that was generated.
-     *
-     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
-     * class and associated utilities which are found in the ASM source jar. Since we don't
-     * want that dependency in the source code, we only put it manually for development and
-     * access the TraceClassVisitor via reflection if present.
-     *
-     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
-     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
-     * @return Either original {@code t} or a new wrapper {@link Throwable}
-     */
-    private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
-        try {
-            // For debugging, dump the bytecode of the class in case of unexpected error
-            // if we can find the TraceClassVisitor class.
-            Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
-
-            StringBuilder sb = new StringBuilder();
-            sb.append('\n').append(t.getClass().getCanonicalName());
-            if (t.getMessage() != null) {
-                sb.append(": ").append(t.getMessage());
-              }
-
-            for (Entry<String, byte[]> entry : cl2.getByteCode()) {
-                String className = entry.getKey();
-                byte[] bytes = entry.getValue();
-
-                StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
-                // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
-                Constructor<?> cons = tcvClass.getConstructor(pw.getClass());
-                Object tcv = cons.newInstance(pw);
-                ClassReader cr2 = new ClassReader(bytes);
-                cr2.accept((ClassVisitor) tcv, 0 /* flags */);
-
-                sb.append("\nBytecode dump: <").append(className).append(">:\n")
-                  .append(sw.toString());
-            }
-
-            // Re-throw exception with new message
-            return new RuntimeException(sb.toString(), t);
-        } catch (Throwable ignore) {
-            // In case of problem, just throw the original exception as-is.
-            return t;
-        }
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
deleted file mode 100644
index 1a5f653..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LogTest {
-
-    private MockLog mLog;
-
-    @Before
-    public void setUp() throws Exception {
-        mLog = new MockLog();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // pass
-    }
-
-    @Test
-    public void testDebug() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.setVerbose(false);
-        mLog.debug("Test %d", 42);
-        assertEquals("", mLog.getOut());
-
-        mLog.setVerbose(true);
-        mLog.debug("Test %d", 42);
-
-        assertEquals("Test 42\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testInfo() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.info("Test %d", 43);
-
-        assertEquals("Test 43\n", mLog.getOut());
-        assertEquals("", mLog.getErr());
-    }
-
-    @Test
-    public void testError() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        mLog.error("Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertEquals("Test 44\n", mLog.getErr());
-    }
-
-    @Test
-    public void testException() {
-        assertEquals("", mLog.getOut());
-        assertEquals("", mLog.getErr());
-
-        Exception e = new Exception("My Exception");
-        mLog.exception(e, "Test %d", 44);
-
-        assertEquals("", mLog.getOut());
-        assertTrue(mLog.getErr().startsWith("Test 44\njava.lang.Exception: My Exception"));
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
deleted file mode 100644
index de750a3..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-
-public class MockLog extends Log {
-    StringBuilder mOut = new StringBuilder();
-    StringBuilder mErr = new StringBuilder();
-
-    public String getOut() {
-        return mOut.toString();
-    }
-
-    public String getErr() {
-        return mErr.toString();
-    }
-
-    @Override
-    protected void outPrintln(String msg) {
-        mOut.append(msg);
-        mOut.append('\n');
-    }
-
-    @Override
-    protected void errPrintln(String msg) {
-        mErr.append(msg);
-        mErr.append('\n');
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
deleted file mode 100644
index eeb0b10..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringJoiner;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * {@link ClassVisitor} that logs all the calls to the different visit methods so they can be later
- * inspected.
- */
-class LoggingClassVisitor extends ClassVisitor {
-    List<String> mLog = new LinkedList<String>();
-
-    public LoggingClassVisitor() {
-        super(Main.ASM_VERSION);
-    }
-
-    public LoggingClassVisitor(ClassVisitor cv) {
-        super(Main.ASM_VERSION, cv);
-    }
-
-    private static String formatAccess(int access) {
-        StringJoiner modifiers = new StringJoiner(",");
-
-        if ((access & Opcodes.ACC_PUBLIC) != 0) {
-            modifiers.add("public");
-        }
-        if ((access & Opcodes.ACC_PRIVATE) != 0) {
-            modifiers.add("private");
-        }
-        if ((access & Opcodes.ACC_PROTECTED) != 0) {
-            modifiers.add("protected");
-        }
-        if ((access & Opcodes.ACC_STATIC) != 0) {
-            modifiers.add("static");
-        }
-        if ((access & Opcodes.ACC_FINAL) != 0) {
-            modifiers.add("static");
-        }
-
-        return "[" + modifiers.toString() + "]";
-    }
-
-    private void log(String method, String format, Object...args) {
-        mLog.add(
-                String.format("[%s] - %s", method, String.format(format, (Object[]) args))
-        );
-    }
-
-    @Override
-    public void visitOuterClass(String owner, String name, String desc) {
-        log(
-                "visitOuterClass",
-                "owner=%s, name=%s, desc=%s",
-                owner, name, desc
-        );
-
-        super.visitOuterClass(owner, name, desc);
-    }
-
-    @Override
-    public void visitInnerClass(String name, String outerName, String innerName, int access) {
-        log(
-                "visitInnerClass",
-                "name=%s, outerName=%s, innerName=%s, access=%s",
-                name, outerName, innerName, formatAccess(access)
-        );
-
-        super.visitInnerClass(name, outerName, innerName, access);
-    }
-
-    @Override
-    public void visit(int version, int access, String name, String signature, String superName,
-            String[] interfaces) {
-        log(
-                "visit",
-                "version=%d, access=%s, name=%s, signature=%s, superName=%s, interfaces=%s",
-                version, formatAccess(access), name, signature, superName, Arrays.toString(interfaces)
-        );
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-}
-
-class PackageProtectedClass {}
-
-public class PromoteClassClassAdapterTest {
-    private static class PrivateClass {}
-    private static class ClassWithPrivateInnerClass {
-        private class InnerPrivateClass {}
-    }
-
-    @Test
-    public void testInnerClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PrivateClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PromoteClassClassAdapterTest$PrivateClass");
-                add("com.android.tools.layoutlib.create" +
-                        ".PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass");
-            }
-        });
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains(
-                "[visitInnerClass] - " +
-                        "name=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest$PrivateClass, " +
-                        "outerName=com/android/tools/layoutlib/create" +
-                        "/PromoteClassClassAdapterTest, innerName=PrivateClass, access=[public,static]"));
-
-        // Test inner of inner class
-        log.mLog.clear();
-        reader = new ClassReader(ClassWithPrivateInnerClass.class.getName());
-        reader.accept(adapter, 0);
-
-        assertTrue(log.mLog.contains("[visitInnerClass] - " +
-                "name=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass$InnerPrivateClass, " +
-                "outerName=com/android/tools/layoutlib/create" +
-                "/PromoteClassClassAdapterTest$ClassWithPrivateInnerClass, " +
-                "innerName=InnerPrivateClass, access=[public]"));
-
-    }
-
-    @Test
-    public void testProtectedClassPromotion() throws IOException {
-        ClassReader reader = new ClassReader(PackageProtectedClass.class.getName());
-        LoggingClassVisitor log = new LoggingClassVisitor();
-
-        PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
-            {
-                add("com.android.tools.layoutlib.create.PackageProtectedClass");
-            }
-        });
-
-        reader.accept(adapter, 0);
-        assertTrue(log.mLog.contains("[visit] - version=52, access=[public], " +
-                "name=com/android/tools/layoutlib/create/PackageProtectedClass, signature=null, " +
-                "superName=java/lang/Object, interfaces=[]"));
-
-    }
-}
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
deleted file mode 100644
index 6211e73..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/RenameClassAdapterTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package com.android.tools.layoutlib.create;
-
-import static org.junit.Assert.*;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- *
- */
-public class RenameClassAdapterTest {
-
-    private RenameClassAdapter mOuter;
-    private RenameClassAdapter mInner;
-
-    @Before
-    public void setUp() throws Exception {
-        mOuter = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old",
-                                         "org.blah.New");
-
-        mInner = new RenameClassAdapter(null, // cv
-                                         "com.pack.Old$Inner",
-                                         "org.blah.New$Inner");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
-    /**
-     * Renames a type, e.g. "Lcom.package.My;"
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameTypeDesc() {
-
-        // primitive types are left untouched
-        assertEquals("I", mOuter.renameTypeDesc("I"));
-        assertEquals("D", mOuter.renameTypeDesc("D"));
-        assertEquals("V", mOuter.renameTypeDesc("V"));
-
-        // object types that need no renaming are left untouched
-        assertEquals("Lcom.package.MyClass;", mOuter.renameTypeDesc("Lcom.package.MyClass;"));
-        assertEquals("Lcom.package.MyClass;", mInner.renameTypeDesc("Lcom.package.MyClass;"));
-
-        // object types that match the requirements
-        assertEquals("Lorg.blah.New;", mOuter.renameTypeDesc("Lcom.pack.Old;"));
-        assertEquals("Lorg.blah.New$Inner;", mInner.renameTypeDesc("Lcom.pack.Old$Inner;"));
-        // inner classes match the base type which is being renamed
-        assertEquals("Lorg.blah.New$Other;", mOuter.renameTypeDesc("Lcom.pack.Old$Other;"));
-        assertEquals("Lorg.blah.New$Other;", mInner.renameTypeDesc("Lcom.pack.Old$Other;"));
-
-        // arrays
-        assertEquals("[Lorg.blah.New;",  mOuter.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mOuter.renameTypeDesc("[[Lcom.pack.Old;"));
-
-        assertEquals("[Lorg.blah.New;",  mInner.renameTypeDesc("[Lcom.pack.Old;"));
-        assertEquals("[[Lorg.blah.New;", mInner.renameTypeDesc("[[Lcom.pack.Old;"));
-    }
-
-    /**
-     * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
-     * object element, e.g. "[Lcom.package.MyClass;"
-     * If the type doesn't need to be renamed, returns the internal name of the input type.
-     */
-    @Test
-    public void testRenameType() {
-        // Skip. This is actually tested by testRenameTypeDesc above.
-    }
-
-    /**
-     * Renames an internal type name, e.g. "com.package.MyClass".
-     * If the type doesn't need to be renamed, returns the input string as-is.
-     */
-    @Test
-    public void testRenameInternalType() {
-        // an actual FQCN
-        assertEquals("org.blah.New", mOuter.renameInternalType("com.pack.Old"));
-        assertEquals("org.blah.New$Inner", mOuter.renameInternalType("com.pack.Old$Inner"));
-
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-        assertEquals("org.blah.New$Other", mInner.renameInternalType("com.pack.Old$Other"));
-    }
-
-    /**
-     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
-     * return value.
-     */
-    @Test
-    public void testRenameMethodDesc() {
-        assertEquals("(IDLorg.blah.New;[Lorg.blah.New$Inner;)Lorg.blah.New$Other;",
-               mOuter.renameMethodDesc("(IDLcom.pack.Old;[Lcom.pack.Old$Inner;)Lcom.pack.Old$Other;"));
-    }
-
-
-
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
deleted file mode 100644
index 3db3e23..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/StubMethodAdapterTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create;
-
-import com.android.tools.layoutlib.create.dataclass.StubClass;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import java.lang.reflect.Method;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-
-import static org.junit.Assert.*;
-
-public class StubMethodAdapterTest {
-
-    private static final String STUB_CLASS_NAME = StubClass.class.getName();
-
-    /**
-     * Load a dummy class, stub one of its method and ensure that the modified class works as
-     * intended.
-     */
-    @Test
-    public void testBoolean() throws Exception {
-        final String methodName = "returnTrue";
-        // First don't change the method and assert that it returns true
-        testBoolean((name, type) -> false, Assert::assertTrue, methodName);
-        // Change the method now and assert that it returns false.
-        testBoolean((name, type) -> methodName.equals(name) &&
-                Type.BOOLEAN_TYPE.equals(type.getReturnType()), Assert::assertFalse, methodName);
-    }
-
-    /**
-     * @param methodPredicate tests if the method should be replaced
-     */
-    private void testBoolean(BiPredicate<String, Type> methodPredicate, Consumer<Boolean> assertion,
-            String methodName) throws Exception {
-        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        // Always rename the class to avoid conflict with the original class.
-        String newClassName = STUB_CLASS_NAME + '_';
-        new ClassReader(STUB_CLASS_NAME).accept(
-                new ClassAdapter(newClassName, writer, methodPredicate), 0);
-        MyClassLoader myClassLoader = new MyClassLoader(newClassName, writer.toByteArray());
-        Class<?> aClass = myClassLoader.loadClass(newClassName);
-        assertTrue("StubClass not loaded by the classloader. Likely a bug in the test.",
-                myClassLoader.findClassCalled);
-        Method method = aClass.getMethod(methodName);
-        Object o = aClass.newInstance();
-        assertion.accept((Boolean) method.invoke(o));
-    }
-
-    private static class ClassAdapter extends ClassVisitor {
-
-        private final String mClassName;
-        private final BiPredicate<String, Type> mMethodPredicate;
-
-        private ClassAdapter(String className, ClassVisitor cv,
-                BiPredicate<String, Type> methodPredicate) {
-            super(Main.ASM_VERSION, cv);
-            mClassName = className.replace('.', '/');
-            mMethodPredicate = methodPredicate;
-        }
-
-        @Override
-        public void visit(int version, int access, String name, String signature, String superName,
-                String[] interfaces) {
-            super.visit(version, access, mClassName, signature, superName,
-                    interfaces);
-        }
-
-        @Override
-        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
-                String[] exceptions) {
-            // Copied partly from
-            // com.android.tools.layoutlib.create.DelegateClassAdapter.visitMethod()
-            // but not generating the _Original method.
-            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
-            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
-            MethodVisitor originalMethod =
-                    super.visitMethod(access, name, desc, signature, exceptions);
-            Type descriptor = Type.getMethodType(desc);
-            if (mMethodPredicate.test(name, descriptor)) {
-                String methodSignature = mClassName + "#" + name;
-                String invokeSignature = methodSignature + desc;
-                return new StubMethodAdapter(originalMethod, name, descriptor.getReturnType(),
-                        invokeSignature, isStatic, isNative);
-            }
-            return originalMethod;
-        }
-    }
-
-    private static class MyClassLoader extends ClassLoader {
-        private final String mName;
-        private final byte[] mBytes;
-        private boolean findClassCalled;
-
-        private MyClassLoader(String name, byte[] bytes) {
-            mName = name;
-            mBytes = bytes;
-        }
-
-        @Override
-        protected Class<?> findClass(String name) throws ClassNotFoundException {
-            if (name.equals(mName)) {
-                findClassCalled = true;
-                return defineClass(name, mBytes, 0, mBytes.length);
-            }
-            return super.findClass(name);
-        }
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
deleted file mode 100644
index c314853..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Dummy test class with a native method.
- * The native method is not defined and any attempt to invoke it will
- * throw an {@link UnsatisfiedLinkError}.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative {
-    public ClassWithNative() {
-    }
-
-    public int add(int a, int b) {
-        return a + b;
-    }
-
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-
-    public int callNativeInstance(int a, double d, Object[] o) {
-        return native_instance(a, d, o);
-    }
-
-    private native int native_instance(int a, double d, Object[] o);
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
deleted file mode 100644
index a3d4dc6..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * The delegate that receives the call to {@link ClassWithNative_Delegate}'s overridden methods.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class ClassWithNative_Delegate {
-    public static int native_instance(ClassWithNative instance, int a, double d, Object[] o) {
-        if (o != null && o.length > 0) {
-            o[0] = instance;
-        }
-        return (int)(a + d);
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
deleted file mode 100644
index 9b5a918..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-public final class JavaClass {
-
-    public static final String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
deleted file mode 100644
index 6dfb816..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Test class with an inner class.
- *
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass {
-    private int mOuterValue = 1;
-    public OuterClass() {
-    }
-
-    // Outer.get returns 1 + a + b
-    // Note: it's good to have a long or double for testing parameters since they take
-    // 2 slots in the stack/locals maps.
-    public int get(int a, long b) {
-        return mOuterValue + a + (int) b;
-    }
-
-    public class InnerClass {
-        public InnerClass() {
-        }
-
-        // Inner.get returns 2 + 1 + a + b
-        public int get(int a, long b) {
-            return 2 + mOuterValue + a + (int) b;
-        }
-    }
-
-    public static class StaticInnerClass {
-        public StaticInnerClass() {
-        }
-
-        // StaticInnerClass.get returns 100 + a + b
-        public int get(int a, long b) {
-            return 100 + a + (int) b;
-        }
-    }
-
-    @SuppressWarnings("unused")
-    private String privateMethod() {
-        return "outerPrivateMethod";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
deleted file mode 100644
index 774be8e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_Delegate {
-    // The delegate override of Outer.get returns 4 + a + b
-    public static int get(OuterClass instance, int a, long b) {
-        return 4 + a + (int) b;
-    }
-
-    public static String privateMethod(OuterClass instance) {
-        return "outerPrivate_Delegate";
-    }
-}
-
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
deleted file mode 100644
index b472220..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_InnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(OuterClass outer, InnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
deleted file mode 100644
index a29439e..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_StaticInnerClass_Delegate.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
-import com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass;
-
-/**
- * Used by {@link DelegateClassAdapterTest}.
- */
-public class OuterClass_StaticInnerClass_Delegate {
-    // The delegate override of Inner.get return 6 + a + b
-    public static int get(StaticInnerClass inner, int a, long b) {
-        return 6 + a + (int) b;
-    }
-}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
deleted file mode 100644
index 3ae8e47..0000000
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/StubClass.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.layoutlib.create.dataclass;
-
-import com.android.tools.layoutlib.create.StubMethodAdapterTest;
-
-/**
- * Used by {@link StubMethodAdapterTest}
- */
-@SuppressWarnings("unused")
-public class StubClass {
-
-    public boolean returnTrue() {
-        return true;
-    }
-}
diff --git a/tools/layoutlib/create/tests/data/mock_android.jar b/tools/layoutlib/create/tests/data/mock_android.jar
deleted file mode 100644
index c6ca3c4..0000000
--- a/tools/layoutlib/create/tests/data/mock_android.jar
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java b/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
deleted file mode 100644
index 59612e9..0000000
--- a/tools/layoutlib/create/tests/mock_data/java/lang/JavaClass.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang;
-
-public class JavaClass {
-
-    public static String test = "test";
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
deleted file mode 100644
index ab29fbe..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/anotherDataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should *not* be copied to the output jar.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile b/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
deleted file mode 100644
index 9b01893..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/data/dataFile
+++ /dev/null
@@ -1 +0,0 @@
-A simple data file that should be copied to the output jar unchanged.
\ No newline at end of file
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java b/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
deleted file mode 100644
index d3a1d05..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/dummy/InnerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.dummy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-public class InnerTest {
-
-    private int mSomeField;
-    private MyStaticInnerClass mInnerInstance;
-    private MyIntEnum mTheIntEnum;
-    private MyGenerics1<int[][], InnerTest, MyIntEnum, float[]> mGeneric1;
-
-    public class NotStaticInner2 extends NotStaticInner1 {
-
-    }
-
-    public class NotStaticInner1 {
-
-        public void someThing() {
-            mSomeField = 2;
-            mInnerInstance = null;
-        }
-
-    }
-
-    private static class MyStaticInnerClass {
-
-    }
-    
-    private static class DerivingClass extends InnerTest {
-        
-    }
-    
-    // enums are a kind of inner static class
-    public enum MyIntEnum {
-        VALUE0(0),
-        VALUE1(1),
-        VALUE2(2);
-
-        MyIntEnum(int myInt) {
-            this.myInt = myInt;
-        }
-        final int myInt;
-    }
-    
-    public static class MyGenerics1<T, U, V, W> {
-        public MyGenerics1() {
-            int a = 1;
-        }
-    }
-    
-    public <X> void genericMethod1(X a, X[] b) {
-    }
-
-    public <X, Y> void genericMethod2(X a, List<Y> b) {
-    }
-
-    public <X, Y extends InnerTest> void genericMethod3(X a, List<Y> b) {
-    }
-
-    public <T extends InnerTest> void genericMethod4(T[] a, Collection<T> b, Collection<?> c) {
-        Iterator<T> i = b.iterator();
-    }
-
-    public void someMethod(InnerTest self) {
-        mSomeField = self.mSomeField;
-        MyStaticInnerClass m = new MyStaticInnerClass();
-        mInnerInstance = m;
-        mTheIntEnum = null;
-        mGeneric1 = new MyGenerics1();
-        genericMethod4(new DerivingClass[0], new ArrayList<DerivingClass>(), new ArrayList<InnerTest>());
-    }
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java b/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
deleted file mode 100644
index aaeebf6..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/util/EmptyArray.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.util;
-
-import java.lang.JavaClass;
-
-public class EmptyArray {
-
-        public static final Object[] OBJECT = new Object[0];
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
deleted file mode 100644
index 84ec8a9..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/View.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-import java.lang.JavaClass;
-
-public class View {
-
-        String x = JavaClass.test;
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java b/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
deleted file mode 100644
index 466470f..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/view/ViewGroup.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.view;
-
-public class ViewGroup extends View {
-
-    public class MarginLayoutParams extends LayoutParams {
-
-    }
-
-    public class LayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
deleted file mode 100644
index af56c4b..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/LinearLayout.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.util.EmptyArray;
-import mock_android.view.ViewGroup;
-
-public class LinearLayout extends ViewGroup {
-
-    Object[] mObjects = EmptyArray.OBJECT;
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java b/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
deleted file mode 100644
index e455e7d..0000000
--- a/tools/layoutlib/create/tests/mock_data/mock_android/widget/TableLayout.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package mock_android.widget;
-
-import mock_android.view.ViewGroup;
-
-public class TableLayout extends ViewGroup {
-
-    public class LayoutParams extends MarginLayoutParams {
-
-    }
-
-}
diff --git a/tools/layoutlib/legacy/Android.mk b/tools/layoutlib/legacy/Android.mk
deleted file mode 100644
index 5855f89..0000000
--- a/tools/layoutlib/legacy/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_JAVA_LIBRARIES := \
-	layoutlib_api-prebuilt
-
-LOCAL_MODULE := layoutlib-legacy
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tools/layoutlib/legacy/legacy.iml b/tools/layoutlib/legacy/legacy.iml
deleted file mode 100644
index a167a75..0000000
--- a/tools/layoutlib/legacy/legacy.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
deleted file mode 100644
index 0cfc181..0000000
--- a/tools/layoutlib/legacy/src/com/android/layoutlib/bridge/Bridge.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.Result.Status;
-import com.android.ide.common.rendering.api.SessionParams;
-
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-
-/**
- * Legacy Bridge used in the SDK version of layoutlib
- */
-public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
-    private static final String SDK_NOT_SUPPORTED = "The SDK layoutlib version is not supported";
-    private static final Result NOT_SUPPORTED_RESULT =
-            Status.NOT_IMPLEMENTED.createResult(SDK_NOT_SUPPORTED);
-    private static BufferedImage sImage;
-
-    private static class BridgeRenderSession extends RenderSession {
-
-        @Override
-        public synchronized BufferedImage getImage() {
-            if (sImage == null) {
-                sImage = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
-                Graphics2D g = sImage.createGraphics();
-                g.clearRect(0, 0, 500, 500);
-                g.drawString(SDK_NOT_SUPPORTED, 20, 20);
-                g.dispose();
-            }
-
-            return sImage;
-        }
-
-        @Override
-        public Result render(long timeout, boolean forceMeasure) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result measure(long timeout) {
-            return NOT_SUPPORTED_RESULT;
-        }
-
-        @Override
-        public Result getResult() {
-            return NOT_SUPPORTED_RESULT;
-        }
-    }
-
-
-    @Override
-    public RenderSession createSession(SessionParams params) {
-        return new BridgeRenderSession();
-    }
-
-    @Override
-    public int getApiLevel() {
-        return 0;
-    }
-}
diff --git a/tools/layoutlib/rename_font/README b/tools/layoutlib/rename_font/README
deleted file mode 100644
index 600b756..0000000
--- a/tools/layoutlib/rename_font/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This tool is used to rename the PS name encoded inside the ttf font that we ship
-with the SDK. There is bug in Java that returns incorrect results for
-java.awt.Font#layoutGlyphVector() if two fonts with same name but differnt
-versions are loaded. As a workaround, we rename all the fonts that we ship with
-the SDK by appending the font version to its name.
-
-
-The build_font.py copies all files from input_dir to output_dir while renaming
-the font files (*.ttf) in the process.
diff --git a/tools/layoutlib/rename_font/Roboto-Regular.ttf b/tools/layoutlib/rename_font/Roboto-Regular.ttf
deleted file mode 100644
index 7469063..0000000
--- a/tools/layoutlib/rename_font/Roboto-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/rename_font/build_font.py b/tools/layoutlib/rename_font/build_font.py
deleted file mode 100755
index 9713a4cc..0000000
--- a/tools/layoutlib/rename_font/build_font.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Rename the PS name of all fonts in the input directories and copy them to the
-output directory.
-
-Usage: build_font.py /path/to/input_fonts1/ /path/to/input_fonts2/ /path/to/output_fonts/
-
-"""
-
-import glob
-from multiprocessing import Pool
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-# global variable
-dest_dir = '/tmp'
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-
-def main(argv):
-  if len(argv) < 2:
-    sys.exit('Usage: build_font.py /path/to/input_fonts/ /path/to/out/dir/')
-  for directory in argv:
-    if not os.path.isdir(directory):
-      sys.exit(directory + ' is not a valid directory')
-  global dest_dir
-  dest_dir = argv[-1]
-  src_dirs = argv[:-1]
-  cwd = os.getcwd()
-  os.chdir(dest_dir)
-  files = glob.glob('*')
-  for filename in files:
-    os.remove(filename)
-  os.chdir(cwd)
-  input_fonts = list()
-  for src_dir in src_dirs:
-    for dirname, dirnames, filenames in os.walk(src_dir):
-      for filename in filenames:
-        input_path = os.path.join(dirname, filename)
-        extension = os.path.splitext(filename)[1].lower()
-        if extension == '.ttf':
-          input_fonts.append(input_path)
-        elif extension == '.xml':
-          shutil.copy(input_path, dest_dir)
-      if '.git' in dirnames:
-        # don't go into any .git directories.
-        dirnames.remove('.git')
-  # Create as many threads as the number of CPUs
-  pool = Pool(processes=None)
-  pool.map(convert_font, input_fonts)
-
-
-def convert_font(input_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = os.path.join(dest_dir, filename)
-  ttx_path = ttx_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-d', dest_dir, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-d', dest_dir, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_dir)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/build_font_single.py b/tools/layoutlib/rename_font/build_font_single.py
deleted file mode 100755
index 4245cdc..0000000
--- a/tools/layoutlib/rename_font/build_font_single.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the 'License');
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an 'AS IS' BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Rename the PS name of the input font.
-
-OpenType fonts (*.otf) are not currently supported. They are copied to the destination without renaming.
-XML files are also copied in case they are passed there by mistake.
-
-Usage: build_font_single.py /path/to/input_font.ttf /path/to/output_font.ttf
-
-"""
-
-import glob
-import os
-import re
-import shutil
-import sys
-import xml.etree.ElementTree as etree
-
-# Prevent .pyc files from being created.
-sys.dont_write_bytecode = True
-
-# fontTools is available at platform/external/fonttools
-from fontTools import ttx
-
-
-class FontInfo(object):
-  family = None
-  style = None
-  version = None
-  ends_in_regular = False
-  fullname = None
-
-
-class InvalidFontException(Exception):
-  pass
-
-
-# A constant to copy the font without modifying. This is useful when running
-# locally and speed up the time to build the SDK.
-COPY_ONLY = False
-
-# These constants represent the value of nameID parameter in the namerecord for
-# different information.
-# see http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#3054f18b
-NAMEID_FAMILY = 1
-NAMEID_STYLE = 2
-NAMEID_FULLNAME = 4
-NAMEID_VERSION = 5
-
-# A list of extensions to process.
-EXTENSIONS = ['.ttf', '.otf', '.xml']
-
-def main(argv):
-  if len(argv) < 2:
-    print 'Incorrect usage: ' + str(argv)
-    sys.exit('Usage: build_font_single.py /path/to/input/font.ttf /path/to/out/font.ttf')
-  dest_path = argv[-1]
-  input_path = argv[0]
-  extension = os.path.splitext(input_path)[1].lower()
-  if extension in EXTENSIONS:
-    if not COPY_ONLY and extension == '.ttf':
-      convert_font(input_path, dest_path)
-      return
-    shutil.copy(input_path, dest_path)
-
-
-def convert_font(input_path, dest_path):
-  filename = os.path.basename(input_path)
-  print 'Converting font: ' + filename
-  # the path to the output file. The file name is the fontfilename.ttx
-  ttx_path = dest_path[:-1] + 'x'
-  try:
-    # run ttx to generate an xml file in the output folder which represents all
-    # its info
-    ttx_args = ['-q', '-o', ttx_path, input_path]
-    ttx.main(ttx_args)
-    # now parse the xml file to change its PS name.
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    for name in root.iter('name'):
-      update_tag(name, get_font_info(name))
-    tree.write(ttx_path, xml_declaration=True, encoding='utf-8')
-    # generate the udpated font now.
-    ttx_args = ['-q', '-o', dest_path, ttx_path]
-    ttx.main(ttx_args)
-  except InvalidFontException:
-    # In case of invalid fonts, we exit.
-    print filename + ' is not a valid font'
-    raise
-  except Exception as e:
-    print 'Error converting font: ' + filename
-    print e
-    # Some fonts are too big to be handled by the ttx library.
-    # Just copy paste them.
-    shutil.copy(input_path, dest_path)
-  try:
-    # delete the temp ttx file is it exists.
-    os.remove(ttx_path)
-  except OSError:
-    pass
-
-
-def get_font_info(tag):
-  """ Returns a list of FontInfo representing the various sets of namerecords
-      found in the name table of the font. """
-  fonts = []
-  font = None
-  last_name_id = sys.maxint
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      # A new font should be created for each platform, encoding and language
-      # id. But, since the nameIDs are sorted, we use the easy approach of
-      # creating a new one when the nameIDs reset.
-      if name_id <= last_name_id and font is not None:
-        fonts.append(font)
-        font = None
-      last_name_id = name_id
-      if font is None:
-        font = FontInfo()
-      if name_id == NAMEID_FAMILY:
-        font.family = namerecord.text.strip()
-      if name_id == NAMEID_STYLE:
-        font.style = namerecord.text.strip()
-      if name_id == NAMEID_FULLNAME:
-        font.ends_in_regular = ends_in_regular(namerecord.text)
-        font.fullname = namerecord.text.strip()
-      if name_id == NAMEID_VERSION:
-        font.version = get_version(namerecord.text)
-  if font is not None:
-    fonts.append(font)
-  return fonts
-
-
-def update_tag(tag, fonts):
-  last_name_id = sys.maxint
-  fonts_iterator = fonts.__iter__()
-  font = None
-  for namerecord in tag.iter('namerecord'):
-    if 'nameID' in namerecord.attrib:
-      name_id = int(namerecord.attrib['nameID'])
-      if name_id <= last_name_id:
-        font = fonts_iterator.next()
-        font = update_font_name(font)
-      last_name_id = name_id
-      if name_id == NAMEID_FAMILY:
-        namerecord.text = font.family
-      if name_id == NAMEID_FULLNAME:
-        namerecord.text = font.fullname
-
-
-def update_font_name(font):
-  """ Compute the new font family name and font fullname. If the font has a
-      valid version, it's sanitized and appended to the font family name. The
-      font fullname is then created by joining the new family name and the
-      style. If the style is 'Regular', it is appended only if the original font
-      had it. """
-  if font.family is None or font.style is None:
-    raise InvalidFontException('Font doesn\'t have proper family name or style')
-  if font.version is not None:
-    new_family = font.family + font.version
-  else:
-    new_family = font.family
-  if font.style is 'Regular' and not font.ends_in_regular:
-    font.fullname = new_family
-  else:
-    font.fullname = new_family + ' ' + font.style
-  font.family = new_family
-  return font
-
-
-def ends_in_regular(string):
-  """ According to the specification, the font fullname should not end in
-      'Regular' for plain fonts. However, some fonts don't obey this rule. We
-      keep the style info, to minimize the diff. """
-  string = string.strip().split()[-1]
-  return string is 'Regular'
-
-
-def get_version(string):
-  string = string.strip()
-  # The spec says that the version string should start with "Version ". But not
-  # all fonts do. So, we return the complete string if it doesn't start with
-  # the prefix, else we return the rest of the string after sanitizing it.
-  prefix = 'Version '
-  if string.startswith(prefix):
-    string = string[len(prefix):]
-  return sanitize(string)
-
-
-def sanitize(string):
-  """ Remove non-standard chars. """
-  return re.sub(r'[^\w-]+', '', string)
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/tools/layoutlib/rename_font/test.py b/tools/layoutlib/rename_font/test.py
deleted file mode 100755
index 2ffddf4..0000000
--- a/tools/layoutlib/rename_font/test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-"""Tests build_font.py by renaming a font.
-
-The test copies Roboto-Regular.ttf to a tmp directory and ask build_font.py to rename it and put in another dir.
-We then use ttx to dump the new font to its xml and check if rename was successful
-
-To test locally, use:
-PYTHONPATH="$PYTHONPATH:/path/to/android/checkout/external/fonttools/Lib" ./test.py
-"""
-
-import unittest
-import build_font
-
-from fontTools import ttx
-import os
-import xml.etree.ElementTree as etree
-import shutil
-import tempfile
-
-class MyTest(unittest.TestCase):
-  def test(self):
-    font_name = "Roboto-Regular.ttf"
-    srcdir = tempfile.mkdtemp()
-    print "srcdir: " + srcdir
-    shutil.copy(font_name, srcdir)
-    destdir = tempfile.mkdtemp()
-    print "destdir: " + destdir
-    self.assertTrue(build_font.main([srcdir, destdir]) is None)
-    out_path = os.path.join(destdir, font_name)
-    ttx.main([out_path])
-    ttx_path = out_path[:-1] + "x"
-    tree = etree.parse(ttx_path)
-    root = tree.getroot()
-    name_tag = root.find('name')
-    fonts = build_font.get_font_info(name_tag)
-    shutil.rmtree(srcdir)
-    shutil.rmtree(destdir)
-    self.assertEqual(fonts[0].family, "Roboto1200310")
-    self.assertEqual(fonts[0].fullname, "Roboto1200310 Regular")
-
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
deleted file mode 100644
index ecf39b3..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * {@link ViewGroup} that wraps another view and catches any possible exceptions that the child view
- * might generate.
- * This is used by the theme editor to stop custom views from breaking the preview.
- */
-// TODO: This view is just a temporary solution that will be replaced by adding a try / catch
-// for custom views in the ClassConverter
-public class ErrorCatcher extends ViewGroup {
-    public ErrorCatcher(Context context) {
-        super(context);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            measureChild(child, widthMeasureSpec, heightMeasureSpec);
-
-            setMeasuredDimension(resolveSize(child.getMeasuredWidth(), widthMeasureSpec),
-                    resolveSize(child.getMeasuredHeight(), heightMeasureSpec));
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onMeasure for view " +
-                    child.getClass().getCanonicalName(), t);
-            setMeasuredDimension(resolveSize(0, widthMeasureSpec),
-                    resolveSize(0, heightMeasureSpec));
-        }
-    }
-
-    @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        try {
-            return super.drawChild(canvas, child, drawingTime);
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to draw for view " +
-                    child.getClass().getCanonicalName(), t);
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
-        } catch (Throwable e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onLayout for view " +
-                    child.getClass().getCanonicalName(), e);
-        }
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
deleted file mode 100644
index 4320157..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-@SuppressWarnings("unused")
-public class PressedButton extends Button {
-    public PressedButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setPressed(true);
-        jumpDrawablesToCurrentState();
-    }
-}
diff --git a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java b/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
deleted file mode 100644
index af89910..0000000
--- a/tools/layoutlib/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Custom layout used in the theme editor to display the component preview. It arranges the child
- * Views as a grid of cards.
- * <p/>
- * The Views are measured and the maximum width and height are used to dimension all the child
- * components. Any margin attributes from the children are ignored and only the item_margin element
- * is used.
- */
-@SuppressWarnings("unused")
-public class ThemePreviewLayout extends ViewGroup {
-    private final int mMaxColumns;
-    private final int mMaxColumnWidth;
-    private final int mMinColumnWidth;
-    private final int mItemHorizontalMargin;
-    private final int mItemVerticalMargin;
-
-    /** Item width to use for every card component. This includes margins. */
-    private int mItemWidth;
-    /** Item height to use for every card component. This includes margins. */
-    private int mItemHeight;
-
-    /** Calculated number of columns */
-    private int mNumColumns;
-
-    public ThemePreviewLayout(Context context) {
-        this(context, null);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        if (attrs == null) {
-            mMaxColumnWidth = Integer.MAX_VALUE;
-            mMinColumnWidth = 0;
-            mMaxColumns = Integer.MAX_VALUE;
-            mItemHorizontalMargin = 0;
-            mItemVerticalMargin = 0;
-            return;
-        }
-
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxColumnWidth = attrs.getAttributeIntValue(null, "max_column_width", Integer
-                .MAX_VALUE);
-        int minColumnWidth = attrs.getAttributeIntValue(null, "min_column_width", 0);
-        int itemHorizontalMargin = attrs.getAttributeIntValue(null, "item_horizontal_margin", 0);
-        int itemVerticalMargin = attrs.getAttributeIntValue(null, "item_vertical_margin", 0);
-
-        mMaxColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                maxColumnWidth,
-                dm);
-        mMinColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                minColumnWidth,
-                dm);
-        mItemHorizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemHorizontalMargin,
-                dm);
-        mItemVerticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemVerticalMargin,
-                dm);
-        mMaxColumns = attrs.getAttributeIntValue(null, "max_columns", Integer.MAX_VALUE);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Measure the column size.
-        // The column has a minimum width that will be used to calculate the maximum number of
-        // columns that we can fit in the available space.
-        //
-        // Once we have the maximum number of columns, we will span all columns width evenly to fill
-        // all the available space.
-        int wSize = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
-
-        // Calculate the desired width of all columns and take the maximum.
-        // This step can be skipped if we have a fixed column height so we do not have to
-        // dynamically calculate it.
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int itemWidth = 0;
-        int itemHeight = 0;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-
-            itemWidth = Math.max(itemWidth, v.getMeasuredWidth());
-            itemHeight = Math.max(itemHeight, v.getMeasuredHeight());
-        }
-
-        itemWidth = Math.min(Math.max(itemWidth, mMinColumnWidth), mMaxColumnWidth);
-        mNumColumns = Math.min((int) Math.ceil((double) wSize / itemWidth), mMaxColumns);
-
-        // Check how much space this distribution would take taking into account the margins.
-        // If it's bigger than what we have, remove one column.
-        int wSizeNeeded = mNumColumns * itemWidth + (mNumColumns - 1) * mItemHorizontalMargin;
-        if (wSizeNeeded > wSize && mNumColumns > 1) {
-            mNumColumns--;
-        }
-
-        if (getChildCount() < mNumColumns) {
-            mNumColumns = getChildCount();
-        }
-        if (mNumColumns == 0) {
-            mNumColumns = 1;
-        }
-
-        // Inform each child of the measurement
-        childWidthSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
-        childHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-        }
-
-        // Calculate the height of the first column to measure our own size
-        int firstColumnItems = getChildCount() / mNumColumns + ((getChildCount() % mNumColumns) > 0
-                ? 1 : 0);
-
-        int horizontalMarginsTotalWidth = (mNumColumns - 1) * mItemHorizontalMargin;
-        int verticalMarginsTotalHeight = (firstColumnItems - 1) * mItemVerticalMargin;
-        int totalWidth = mNumColumns * itemWidth + horizontalMarginsTotalWidth +
-                mPaddingRight + mPaddingLeft;
-        int totalHeight = firstColumnItems * itemHeight + verticalMarginsTotalHeight +
-                mPaddingBottom + mPaddingTop;
-
-        setMeasuredDimension(resolveSize(totalWidth, widthMeasureSpec),
-                resolveSize(totalHeight, heightMeasureSpec));
-
-        mItemWidth = itemWidth;
-        mItemHeight = itemHeight;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int itemsPerColumn = getChildCount() / mNumColumns;
-        // The remainder items are distributed one per column.
-        int remainderItems = getChildCount() % mNumColumns;
-
-        int x = mPaddingLeft;
-        int y = mPaddingTop;
-        int position = 1;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-            v.layout(x,
-                    y,
-                    x + mItemWidth,
-                    y + mItemHeight);
-
-            if (position == itemsPerColumn + (remainderItems > 0 ? 1 : 0)) {
-                // Break column
-                position = 1;
-                remainderItems--;
-                x += mItemWidth + mItemHorizontalMargin;
-                y = mPaddingTop;
-            } else {
-                position++;
-                y += mItemHeight + mItemVerticalMargin;
-            }
-        }
-    }
-}
-
-
diff --git a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml b/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
deleted file mode 100644
index b0363d7..0000000
--- a/tools/layoutlib/studio-custom-widgets/studio-android-widgets.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module" module-name="bridge" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index 1b1f63e..6dc306e 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -39,7 +39,7 @@
 LOCAL_CFLAGS := -Wall -Werror -Wno-mismatched-tags
 LOCAL_SRC_FILES := pbkdf2gen.cpp
 LOCAL_LDLIBS += -ldl
-LOCAL_STATIC_LIBRARIES := libcrypto_static
+LOCAL_STATIC_LIBRARIES := libcrypto
 
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index e152f6c..eeabbfa 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -161,6 +161,16 @@
                 }
             };
 
+    /**
+     * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a
+     * data-path created without a corresponding Aware discovery session.
+     *
+     * @hide
+     */
+    public boolean isOutOfBand() {
+        return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index b34fcdc..adf897d 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -336,14 +336,13 @@
      */
     @Test
     public void testCorrectLooperIsUsedForHandler() throws Exception {
-        // record thread from looper.getThread and check ids.
         TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
         when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
                 .thenReturn(ERROR_INCOMPATIBLE_MODE);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
-        assertEquals(mLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
+        verify(mContext, never()).getMainLooper();
     }
 
     /**
@@ -362,6 +361,7 @@
         altLooper.dispatchAll();
         assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
         assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
+        verify(mContext).getMainLooper();
     }
 
     /**
@@ -632,12 +632,11 @@
      */
     @Test
     public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
-        // record thread from looper.getThread and check ids.
         TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
         mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
         mLooper.dispatchAll();
         assertTrue(observer.mOnRegistered);
-        assertEquals(mLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
+        verify(mContext, never()).getMainLooper();
     }
 
     /**
@@ -654,6 +653,7 @@
         altLooper.dispatchAll();
         assertTrue(observer.mOnRegistered);
         assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
+        verify(mContext).getMainLooper();
     }
 
     /**