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

Commit 30693713 authored by Jason Monk's avatar Jason Monk Committed by Android (Google) Code Review
Browse files

Merge "Add suggestions parsing to SettingsLib"

parents 9f172e65 f509d7e6
Loading
Loading
Loading
Loading
+177 −0
Original line number Diff line number Diff line
/*
 * 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.settingslib;

import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
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;

public class SuggestionParser {

    private static final String TAG = "SuggestionParser";

    private final Context mContext;
    private final List<SuggestionCategory> mSuggestionList;
    private final ArrayMap<Pair<String, String>, Tile> addCache = new ArrayMap<>();

    public SuggestionParser(Context context, int orderXml) {
        mContext = context;
        mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
                .parse(orderXml);
    }

    public List<Tile> getSuggestions() {
        List<Tile> suggestions = new ArrayList<>();
        final int N = mSuggestionList.size();
        for (int i = 0; i < N; i++) {
            readSuggestions(mSuggestionList.get(i), suggestions);
        }
        return suggestions;
    }

    private void readSuggestions(SuggestionCategory category, List<Tile> suggestions) {
        int countBefore = suggestions.size();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(category.category);
        if (category.pkg != null) {
            intent.setPackage(category.pkg);
        }
        TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
                addCache, null, suggestions, true, false);
        if (!category.multiple && suggestions.size() > (countBefore + 1)) {
            // If there are too many, remove them all and only re-add the one with the highest
            // priority.
            Tile item = suggestions.remove(suggestions.size() - 1);
            while (suggestions.size() > countBefore) {
                Tile last = suggestions.remove(suggestions.size() - 1);
                if (last.priority > item.priority) {
                    item = last;
                }
            }
            suggestions.add(item);
        }
    }

    private static class SuggestionCategory {
        public String category;
        public String pkg;
        public boolean multiple;
    }

    private static class SuggestionOrderInflater {
        private static final String TAG_LIST = "optional-steps";
        private static final String TAG_ITEM = "step";

        private static final String ATTR_CATEGORY = "category";
        private static final String ATTR_PACKAGE = "package";
        private static final String ATTR_MULTIPLE = "multiple";

        private final Context mContext;

        public SuggestionOrderInflater(Context context) {
            mContext = context;
        }

        public Object parse(int resource) {
            XmlPullParser parser = mContext.getResources().getXml(resource);
            final AttributeSet attrs = Xml.asAttributeSet(parser);
            try {
                // Look for the root node.
                int type;
                do {
                    type = parser.next();
                } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);

                if (type != XmlPullParser.START_TAG) {
                    throw new InflateException(parser.getPositionDescription()
                            + ": No start tag found!");
                }

                // Temp is the root that was found in the xml
                Object xmlRoot = onCreateItem(parser.getName(), attrs);

                // Inflate all children under temp
                rParse(parser, xmlRoot, attrs);
                return xmlRoot;
            } catch (XmlPullParserException | IOException e) {
                Log.w(TAG, "Problem parser resource " + resource, e);
                return null;
            }
        }

        /**
         * Recursive method used to descend down the xml hierarchy and instantiate
         * items, instantiate their children.
         */
        private void rParse(XmlPullParser parser, Object parent, final AttributeSet attrs)
                throws XmlPullParserException, IOException {
            final int depth = parser.getDepth();

            int type;
            while (((type = parser.next()) != XmlPullParser.END_TAG ||
                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
                if (type != XmlPullParser.START_TAG) {
                    continue;
                }

                final String name = parser.getName();

                Object item = onCreateItem(name, attrs);
                onAddChildItem(parent, item);
                rParse(parser, item, attrs);
            }
        }

        protected void onAddChildItem(Object parent, Object child) {
            if (parent instanceof List<?> && child instanceof SuggestionCategory) {
                ((List<SuggestionCategory>) parent).add((SuggestionCategory) child);
            } else {
                throw new IllegalArgumentException("Parent was not a list");
            }
        }

        protected Object onCreateItem(String name, AttributeSet attrs) {
            if (name.equals(TAG_LIST)) {
                return new ArrayList<SuggestionCategory>();
            } else if (name.equals(TAG_ITEM)) {
                SuggestionCategory category = new SuggestionCategory();
                category.category = attrs.getAttributeValue(null, ATTR_CATEGORY);
                category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
                String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
                category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
                return category;
            } else {
                throw new IllegalArgumentException("Unknown item " + name);
            }
        }
    }
}
+7 −7
Original line number Diff line number Diff line
@@ -43,22 +43,22 @@ public class DashboardCategory implements Parcelable {
    /**
     * List of the category's children
     */
    public List<DashboardTile> tiles = new ArrayList<DashboardTile>();
    public List<Tile> tiles = new ArrayList<Tile>();


    public DashboardCategory() {
        // Empty
    }

    public void addTile(DashboardTile tile) {
    public void addTile(Tile tile) {
        tiles.add(tile);
    }

    public void addTile(int n, DashboardTile tile) {
    public void addTile(int n, Tile tile) {
        tiles.add(n, tile);
    }

    public void removeTile(DashboardTile tile) {
    public void removeTile(Tile tile) {
        tiles.remove(tile);
    }

@@ -70,7 +70,7 @@ public class DashboardCategory implements Parcelable {
        return tiles.size();
    }

    public DashboardTile getTile(int n) {
    public Tile getTile(int n) {
        return tiles.get(n);
    }

@@ -89,7 +89,7 @@ public class DashboardCategory implements Parcelable {
        dest.writeInt(count);

        for (int n = 0; n < count; n++) {
            DashboardTile tile = tiles.get(n);
            Tile tile = tiles.get(n);
            tile.writeToParcel(dest, flags);
        }
    }
@@ -102,7 +102,7 @@ public class DashboardCategory implements Parcelable {
        final int count = in.readInt();

        for (int n = 0; n < count; n++) {
            DashboardTile tile = DashboardTile.CREATOR.createFromParcel(in);
            Tile tile = Tile.CREATOR.createFromParcel(in);
            tiles.add(tile);
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -30,9 +30,9 @@ public class ProfileSelectDialog extends DialogFragment implements OnClickListen

    private static final String ARG_SELECTED_TILE = "selectedTile";

    private DashboardTile mSelectedTile;
    private Tile mSelectedTile;

    public static void show(FragmentManager manager, DashboardTile tile) {
    public static void show(FragmentManager manager, Tile tile) {
        ProfileSelectDialog dialog = new ProfileSelectDialog();
        Bundle args = new Bundle();
        args.putParcelable(ARG_SELECTED_TILE, tile);
+3 −3
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ public class SettingsDrawerActivity extends Activity {
    private static final String TAG = "SettingsDrawerActivity";

    private static List<DashboardCategory> sDashboardCategories;
    private static HashMap<Pair<String, String>, DashboardTile> sTileCache;
    private static HashMap<Pair<String, String>, Tile> sTileCache;

    private final PackageReceiver mPackageReceiver = new PackageReceiver();
    private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
@@ -194,7 +194,7 @@ public class SettingsDrawerActivity extends Activity {
        }
    }

    public boolean openTile(DashboardTile tile) {
    public boolean openTile(Tile tile) {
        closeDrawer();
        if (tile == null) {
            return false;
@@ -211,7 +211,7 @@ public class SettingsDrawerActivity extends Activity {
        return true;
    }

    protected void onTileClicked(DashboardTile tile) {
    protected void onTileClicked(Tile tile) {
        if (openTile(tile)) {
            finish();
        }
+3 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ public class SettingsDrawerAdapter extends BaseAdapter {
            mItems.add(category);
            for (int j = 0; j < dashboardCategory.tiles.size(); j++) {
                Item tile = new Item();
                DashboardTile dashboardTile = dashboardCategory.tiles.get(j);
                Tile dashboardTile = dashboardCategory.tiles.get(j);
                tile.label = dashboardTile.title;
                tile.icon = dashboardTile.icon;
                tile.tile = dashboardTile;
@@ -58,7 +58,7 @@ public class SettingsDrawerAdapter extends BaseAdapter {
        notifyDataSetChanged();
    }

    public DashboardTile getTile(int position) {
    public Tile getTile(int position) {
        return mItems.get(position).tile;
    }

@@ -101,6 +101,6 @@ public class SettingsDrawerAdapter extends BaseAdapter {
    private static class Item {
        public Icon icon;
        public CharSequence label;
        public DashboardTile tile;
        public Tile tile;
    }
}
Loading