Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dde331ce authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

We can now (kind-of) change screen density on the fly.

Preloaded drawables now have a density associated with them, so we
can load the correct drawable if we are using a different density.

Window manager now formally keeps track of the density for each
screen, allowing it to be overridden like you can already do with
size, and relies on this density to drive itself internally and
the configurations it reports.

There are a new set of Bitmap constructors where you provide a
DisplayMetrics so they can be constructed with the correct density.
(This will be for when you can have different windows in the same
app running at different densities.)

ActivityThread now watches for density changes, and pushes them
to the DENSITY_DEVICE and Bitmap global density values for that
process.

A new am command allows you to change the density.
parent 5345c310
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -8114,8 +8114,11 @@ package android.graphics {
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int);
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, boolean);
    method public int describeContents();
    method public void eraseColor(int);
@@ -19958,7 +19961,6 @@ package android.service.dreams {
    method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
    method public boolean onSearchRequested();
    method public void onStart();
    method public final int onStartCommand(android.content.Intent, int, int);
    method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
    method public void onWindowFocusChanged(boolean);
    method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
+43 −0
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ public class Am {
            runScreenCompat();
        } else if (op.equals("display-size")) {
            runDisplaySize();
        } else if (op.equals("display-density")) {
            runDisplayDensity();
        } else if (op.equals("to-uri")) {
            runToUri(false);
        } else if (op.equals("to-intent-uri")) {
@@ -1127,6 +1129,44 @@ public class Am {
        }
    }

    private void runDisplayDensity() throws Exception {
        String densityStr = nextArgRequired();
        int density;
        if ("reset".equals(densityStr)) {
            density = -1;
        } else {
            try {
                density = Integer.parseInt(densityStr);
            } catch (NumberFormatException e) {
                System.err.println("Error: bad number " + e);
                showUsage();
                return;
            }
            if (density < 72) {
                System.err.println("Error: density must be >= 72");
                showUsage();
                return;
            }
        }

        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
                Context.WINDOW_SERVICE));
        if (wm == null) {
            System.err.println(NO_SYSTEM_ERROR_CODE);
            throw new AndroidException("Can't connect to window manager; is the system running?");
        }

        try {
            if (density > 0) {
                // TODO(multidisplay): For now Configuration only applies to main screen.
                wm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density);
            } else {
                wm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
            }
        } catch (RemoteException e) {
        }
    }

    private void runToUri(boolean intentScheme) throws Exception {
        Intent intent = makeIntent();
        System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
@@ -1301,6 +1341,7 @@ public class Am {
                "       am monitor [--gdb <port>]\n" +
                "       am screen-compat [on|off] <PACKAGE>\n" +
                "       am display-size [reset|MxN]\n" +
                "       am display-density [reset|DENSITY]\n" +
                "       am to-uri [INTENT]\n" +
                "       am to-intent-uri [INTENT]\n" +
                "\n" +
@@ -1355,6 +1396,8 @@ public class Am {
                "\n" +
                "am display-size: override display size.\n" +
                "\n" +
                "am display-density: override display density.\n" +
                "\n" +
                "am to-uri: print the given Intent specification as a URI.\n" +
                "\n" +
                "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
+29 −11
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ public final class ActivityThread {
    AppBindData mBoundApplication;
    Profiler mProfiler;
    int mCurDefaultDisplayDpi;
    boolean mDensityCompatMode;
    Configuration mConfiguration;
    Configuration mCompatConfiguration;
    Configuration mResConfiguration;
@@ -2733,7 +2734,8 @@ public final class ActivityThread {

                // On platforms where we don't want thumbnails, set dims to (0,0)
                if ((w > 0) && (h > 0)) {
                    thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT);
                    thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
                            w, h, THUMBNAIL_FORMAT);
                    thumbnail.eraseColor(0);
                }
            }
@@ -3468,6 +3470,7 @@ public final class ActivityThread {
        // If there was a pending configuration change, execute it first.
        if (changedConfig != null) {
            mCurDefaultDisplayDpi = changedConfig.densityDpi;
            updateDefaultDensity();
            handleConfigurationChanged(changedConfig, null);
        }

@@ -3718,6 +3721,7 @@ public final class ActivityThread {
                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
                    config = mPendingConfiguration;
                    mCurDefaultDisplayDpi = config.densityDpi;
                    updateDefaultDensity();
                }
                mPendingConfiguration = null;
            }
@@ -3920,6 +3924,18 @@ public final class ActivityThread {
        }
    }

    private void updateDefaultDensity() {
        if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
                && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
                && !mDensityCompatMode) {
            Slog.i(TAG, "Switching default density from "
                    + DisplayMetrics.DENSITY_DEVICE + " to "
                    + mCurDefaultDisplayDpi);
            DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
        }
    }

    private void handleBindApplication(AppBindData data) {
        mBoundApplication = data;
        mConfiguration = new Configuration(data.config);
@@ -3980,6 +3996,16 @@ public final class ActivityThread {

        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

        /**
         * Switch this process to density compatibility mode if needed.
         */
        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
                == 0) {
            mDensityCompatMode = true;
            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
        }
        updateDefaultDensity();

        final ContextImpl appContext = new ContextImpl();
        appContext.init(data.info, null, this);
        final File cacheDir = appContext.getCacheDir();
@@ -4010,14 +4036,6 @@ public final class ActivityThread {
            StrictMode.enableDeathOnNetwork();
        }

        /**
         * Switch this process to density compatibility mode if needed.
         */
        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
                == 0) {
            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
        }

        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
            // XXX should have option to change the port.
            Debug.changeDebugPort(8100);
+41 −12
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ public class Resources {
            = new LongSparseArray<ColorStateList>();
    private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
            = new LongSparseArray<Drawable.ConstantState>();
    private static boolean mPreloaded;
    private static boolean sPreloaded;
    private static int sPreloadedDensity;

    /*package*/ final TypedValue mTmpValue = new TypedValue();
    /*package*/ final Configuration mTmpConfig = new Configuration();
@@ -1837,11 +1838,14 @@ public class Resources {
     */
    public final void startPreloading() {
        synchronized (mSync) {
            if (mPreloaded) {
            if (sPreloaded) {
                throw new IllegalStateException("Resources already preloaded");
            }
            mPreloaded = true;
            sPreloaded = true;
            mPreloading = true;
            sPreloadedDensity = DisplayMetrics.DENSITY_DEVICE;
            mConfiguration.densityDpi = sPreloadedDensity;
            updateConfiguration(null, null);
        }
    }
    
@@ -1856,6 +1860,23 @@ public class Resources {
        }
    }

    private boolean verifyPreloadConfig(TypedValue value, String name) {
        if ((value.changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE
                | ActivityInfo.CONFIG_DENSITY)) != 0) {
            String resName;
            try {
                resName = getResourceName(value.resourceId);
            } catch (NotFoundException e) {
                resName = "?";
            }
            Log.w(TAG, "Preloaded " + name + " resource #0x"
                    + Integer.toHexString(value.resourceId)
                    + " (" + resName + ") that varies with configuration!!");
            return false;
        }
        return true;
    }

    /*package*/ Drawable loadDrawable(TypedValue value, int id)
            throws NotFoundException {

@@ -1879,8 +1900,10 @@ public class Resources {
            return dr;
        }

        Drawable.ConstantState cs = isColorDrawable ?
                sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
        Drawable.ConstantState cs = isColorDrawable
                ? sPreloadedColorDrawables.get(key)
                : (sPreloadedDensity == mConfiguration.densityDpi
                        ? sPreloadedDrawables.get(key) : null);
        if (cs != null) {
            dr = cs.newDrawable(this);
        } else {
@@ -1948,11 +1971,13 @@ public class Resources {
            cs = dr.getConstantState();
            if (cs != null) {
                if (mPreloading) {
                    if (verifyPreloadConfig(value, "drawable")) {
                        if (isColorDrawable) {
                            sPreloadedColorDrawables.put(key, cs);
                        } else {
                            sPreloadedDrawables.put(key, cs);
                        }
                    }
                } else {
                    synchronized (mTmpValue) {
                        //Log.i(TAG, "Saving cached drawable @ #" +
@@ -2016,8 +2041,10 @@ public class Resources {

            csl = ColorStateList.valueOf(value.data);
            if (mPreloading) {
                if (verifyPreloadConfig(value, "color")) {
                    sPreloadedColorStateLists.put(key, csl);
                }
            }

            return csl;
        }
@@ -2060,7 +2087,9 @@ public class Resources {

        if (csl != null) {
            if (mPreloading) {
                if (verifyPreloadConfig(value, "color")) {
                    sPreloadedColorStateLists.put(key, csl);
                }
            } else {
                synchronized (mTmpValue) {
                    //Log.i(TAG, "Saving cached color state list @ #" +
+7 −0
Original line number Diff line number Diff line
@@ -2793,6 +2793,13 @@ public final class Settings {
         */
        public static final String DISPLAY_SIZE_FORCED = "display_size_forced";

        /**
         * The saved value for WindowManagerService.setForcedDisplayDensity().
         * One integer in dpi.  If unset, then use the real display density.
         * @hide
         */
        public static final String DISPLAY_DENSITY_FORCED = "display_density_forced";

        /**
         * Whether assisted GPS should be enabled or not.
         * @hide
Loading