/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES 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.kalab.chess.enginesupport; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.Build; import android.os.Bundle; import android.util.Log; public class ChessEngineResolver { private static final String ENGINE_PROVIDER_MARKER = "intent.chess.provider.ENGINE"; private static final String TAG = ChessEngineResolver.class.getSimpleName(); private Context context; private String target; public ChessEngineResolver(Context context) { super(); this.context = context; this.target = Build.CPU_ABI; sanitizeArmV6Target(); } private void sanitizeArmV6Target() { if (this.target.startsWith("armeabi-v6")) { this.target = "armeabi"; } } public List<ChessEngine> resolveEngines() { List<ChessEngine> result = new ArrayList<ChessEngine>(); final Intent intent = new Intent(ENGINE_PROVIDER_MARKER); List<ResolveInfo> list = context.getPackageManager() .queryIntentActivities(intent, PackageManager.GET_META_DATA); for (ResolveInfo resolveInfo : list) { String packageName = resolveInfo.activityInfo.packageName; result = resolveEnginesForPackage(result, resolveInfo, packageName); } return result; } private List<ChessEngine> resolveEnginesForPackage( List<ChessEngine> result, ResolveInfo resolveInfo, String packageName) { if (packageName != null) { Log.d(TAG, "found engine provider, packageName=" + packageName); Bundle bundle = resolveInfo.activityInfo.metaData; if (bundle != null) { String authority = bundle .getString("chess.provider.engine.authority"); Log.d(TAG, "authority=" + authority); if (authority != null) { try { Resources resources = context .getPackageManager() .getResourcesForApplication( resolveInfo.activityInfo.applicationInfo); int resId = resources.getIdentifier("enginelist", "xml", packageName); XmlResourceParser parser = resources.getXml(resId); parseEngineListXml(parser, authority, result, packageName); } catch (NameNotFoundException e) { Log.e(TAG, e.getLocalizedMessage(), e); } } } } return result; } private void parseEngineListXml(XmlResourceParser parser, String authority, List<ChessEngine> result, String packageName) { try { int eventType = parser.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { String name = null; try { if (eventType == XmlResourceParser.START_TAG) { name = parser.getName(); if (name.equalsIgnoreCase("engine")) { String fileName = parser.getAttributeValue(null, "filename"); String title = parser.getAttributeValue(null, "name"); String targetSpecification = parser .getAttributeValue(null, "target"); String[] targets = targetSpecification.split("\\|"); for (String cpuTarget : targets) { if (target.equals(cpuTarget)) { result.add(new ChessEngine(title, fileName, authority, packageName)); } } } } eventType = parser.next(); } catch (IOException e) { Log.e(TAG, e.getLocalizedMessage(), e); } } } catch (XmlPullParserException e) { Log.e(TAG, e.getLocalizedMessage(), e); } } /** * Don't use this in production - this method is only for testing. Set the * cpu target. * * @param target * the cpu target to set */ public void setTarget(String target) { this.target = target; sanitizeArmV6Target(); } }