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

Commit 1c4ae809 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Allow OEM to specify <unavailable-feature>.

Some single-system-image builds may run on devices that lack
certain hardware features.  This change allows the OEM partition to
mark a feature as "unavailable" which overrides the system image.

Bug: 18801291
Change-Id: I0d81144ec92ee9a78c13b223bbba20a4aed23fa0
parent 28fbe040
Loading
Loading
Loading
Loading
+37 −10
Original line number Original line Diff line number Diff line
@@ -25,7 +25,11 @@ import android.util.ArraySet;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArray;
import android.util.Xml;
import android.util.Xml;

import libcore.io.IoUtils;

import com.android.internal.util.XmlUtils;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserException;


@@ -60,6 +64,10 @@ public class SystemConfig {
    // system configuration files.
    // system configuration files.
    final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>();
    final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>();


    // These are the features which this device doesn't support; the OEM
    // partition uses these to opt-out of features from the system image.
    final ArraySet<String> mUnavailableFeatures = new ArraySet<>();

    public static final class PermissionEntry {
    public static final class PermissionEntry {
        public final String name;
        public final String name;
        public int[] gids;
        public int[] gids;
@@ -145,9 +153,11 @@ public class SystemConfig {
        }
        }


        // Iterate over the files in the directory and scan .xml files
        // Iterate over the files in the directory and scan .xml files
        File platformFile = null;
        for (File f : libraryDir.listFiles()) {
        for (File f : libraryDir.listFiles()) {
            // We'll read platform.xml last
            // We'll read platform.xml last
            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
                platformFile = f;
                continue;
                continue;
            }
            }


@@ -163,10 +173,10 @@ public class SystemConfig {
            readPermissionsFromXml(f, onlyFeatures);
            readPermissionsFromXml(f, onlyFeatures);
        }
        }


        // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
        // Read platform permissions last so it will take precedence
        final File permFile = new File(Environment.getRootDirectory(),
        if (platformFile != null) {
                "etc/permissions/platform.xml");
            readPermissionsFromXml(platformFile, onlyFeatures);
        readPermissionsFromXml(permFile, onlyFeatures);
        }
    }
    }


    private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
    private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
@@ -298,7 +308,18 @@ public class SystemConfig {
                    XmlUtils.skipCurrentTag(parser);
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                    continue;


                } else if ("allow-in-power-save".equals(name)) {
                } else if ("unavailable-feature".equals(name)) {
                    String fname = parser.getAttributeValue(null, "name");
                    if (fname == null) {
                        Slog.w(TAG, "<unavailable-feature> without name at "
                                + parser.getPositionDescription());
                    } else {
                        mUnavailableFeatures.add(fname);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else if ("allow-in-power-save".equals(name) && !onlyFeatures) {
                    String pkgname = parser.getAttributeValue(null, "package");
                    String pkgname = parser.getAttributeValue(null, "package");
                    if (pkgname == null) {
                    if (pkgname == null) {
                        Slog.w(TAG, "<allow-in-power-save> without package at "
                        Slog.w(TAG, "<allow-in-power-save> without package at "
@@ -309,7 +330,7 @@ public class SystemConfig {
                    XmlUtils.skipCurrentTag(parser);
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                    continue;


                } else if ("fixed-ime-app".equals(name)) {
                } else if ("fixed-ime-app".equals(name) && !onlyFeatures) {
                    String pkgname = parser.getAttributeValue(null, "package");
                    String pkgname = parser.getAttributeValue(null, "package");
                    if (pkgname == null) {
                    if (pkgname == null) {
                        Slog.w(TAG, "<fixed-ime-app> without package at "
                        Slog.w(TAG, "<fixed-ime-app> without package at "
@@ -324,13 +345,19 @@ public class SystemConfig {
                    XmlUtils.skipCurrentTag(parser);
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                    continue;
                }
                }

            }
            }
            permReader.close();
        } catch (XmlPullParserException e) {
        } catch (XmlPullParserException e) {
            Slog.w(TAG, "Got execption parsing permissions.", e);
            Slog.w(TAG, "Got exception parsing permissions.", e);
        } catch (IOException e) {
        } catch (IOException e) {
            Slog.w(TAG, "Got execption parsing permissions.", e);
            Slog.w(TAG, "Got exception parsing permissions.", e);
        } finally {
            IoUtils.closeQuietly(permReader);
        }

        for (String fname : mUnavailableFeatures) {
            if (mAvailableFeatures.remove(fname) != null) {
                Slog.d(TAG, "Removed unavailable feature " + fname);
            }
        }
        }
    }
    }