diff --git a/OsmAnd/src/net/osmand/aidl/IOsmAndAidlInterface.aidl b/OsmAnd/src/net/osmand/aidl/IOsmAndAidlInterface.aidl index 4f9fe0e953..d27b1da4e4 100644 --- a/OsmAnd/src/net/osmand/aidl/IOsmAndAidlInterface.aidl +++ b/OsmAnd/src/net/osmand/aidl/IOsmAndAidlInterface.aidl @@ -71,6 +71,8 @@ import net.osmand.aidl.navigation.NavigateSearchParams; import net.osmand.aidl.customization.SetWidgetsParams; import net.osmand.aidl.customization.OsmandSettingsParams; +import net.osmand.aidl.customization.OsmandSettingsInfoParams; +import net.osmand.aidl.customization.CustomizationInfoParams; import net.osmand.aidl.gpx.AGpxFile; import net.osmand.aidl.gpx.AGpxFileDetails; @@ -699,4 +701,8 @@ interface IOsmAndAidlInterface { long addContextMenuButtons(in ContextMenuButtonsParams params, IOsmAndAidlCallback callback); boolean removeContextMenuButtons(in RemoveContextMenuButtonsParams params); boolean updateContextMenuButtons(in UpdateContextMenuButtonsParams params); + + boolean areOsmandSettingsCustomized(in OsmandSettingsInfoParams params); + + boolean setCustomization(in CustomizationInfoParams params); } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index babb41e87d..12178937c2 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -23,7 +23,6 @@ import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.view.View; -import android.widget.ArrayAdapter; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; @@ -33,6 +32,7 @@ import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.aidl.contextmenu.ContextMenuButtonsParams; import net.osmand.aidl.copyfile.CopyFileParams; +import net.osmand.aidl.customization.CustomizationInfoParams; import net.osmand.aidl.favorite.AFavorite; import net.osmand.aidl.favorite.group.AFavoriteGroup; import net.osmand.aidl.gpx.AGpxBitmap; @@ -58,7 +58,6 @@ import net.osmand.plus.AppInitializer.AppInitializeListener; import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.ApplicationMode; import net.osmand.plus.ContextMenuAdapter; -import net.osmand.plus.ContextMenuItem; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GpxSelectionHelper; @@ -109,8 +108,6 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -126,7 +123,6 @@ import static net.osmand.aidl.OsmandAidlConstants.COPY_FILE_WRITE_LOCK_ERROR; import static net.osmand.aidl.OsmandAidlConstants.OK_RESPONSE; import static net.osmand.aidl.OsmandAidlService.KEY_ON_CONTEXT_MENU_BUTTONS_CLICK; import static net.osmand.aidl.OsmandAidlService.KEY_ON_NAV_DATA_UPDATE; -import static net.osmand.plus.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME; public class OsmandAidlApi { @@ -194,8 +190,6 @@ public class OsmandAidlApi { private static final int DEFAULT_ZOOM = 15; - private static final int MAX_NAV_DRAWER_ITEMS_PER_APP = 3; - private OsmandApplication app; private Map widgets = new ConcurrentHashMap<>(); private Map widgetControls = new ConcurrentHashMap<>(); @@ -1738,123 +1732,11 @@ public class OsmandAidlApi { } boolean setNavDrawerItems(String appPackage, List items) { - if (!TextUtils.isEmpty(appPackage) && items != null) { - clearNavDrawerItems(appPackage); - if (items.isEmpty()) { - return true; - } - List newItems = new ArrayList<>(MAX_NAV_DRAWER_ITEMS_PER_APP); - boolean success = true; - for (int i = 0; i < items.size() && i <= MAX_NAV_DRAWER_ITEMS_PER_APP; i++) { - net.osmand.aidl.navdrawer.NavDrawerItem item = items.get(i); - String name = item.getName(); - String uri = item.getUri(); - if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(uri)) { - newItems.add(new NavDrawerItem(name, uri, item.getIconName(), item.getFlags())); - } else { - success = false; - break; - } - } - if (success) { - saveNavDrawerItems(appPackage, newItems); - } - return success; - } - return false; + return app.getAppCustomization().setNavDrawerItems(appPackage, items); } public void registerNavDrawerItems(final Activity activity, ContextMenuAdapter adapter) { - PackageManager pm = activity.getPackageManager(); - for (Map.Entry> entry : getNavDrawerItems().entrySet()) { - String appPackage = entry.getKey(); - for (NavDrawerItem item : entry.getValue()) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.uri)); - if (intent.resolveActivity(pm) == null) { - intent = pm.getLaunchIntentForPackage(appPackage); - } - if (intent != null) { - if (item.flags != -1) { - intent.addFlags(item.flags); - } - final Intent finalIntent = intent; - adapter.addItem(new ContextMenuItem.ItemBuilder() - .setId(item.getId()) - .setTitle(item.name) - .setIcon(getIconId(item.iconName)) - .setListener(new ContextMenuAdapter.ItemClickListener() { - @Override - public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) { - activity.startActivity(finalIntent); - return true; - } - }) - .createItem()); - } - } - } - } - - private int getIconId(@Nullable String iconName) { - if (!TextUtils.isEmpty(iconName)) { - int id = app.getResources().getIdentifier(iconName, "drawable", app.getPackageName()); - return id == 0 ? -1 : id; - } - return -1; - } - - private void clearNavDrawerItems(String appPackage) { - try { - JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); - allItems.put(appPackage, new JSONArray()); - app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - private void saveNavDrawerItems(String appPackage, List items) { - try { - JSONArray jArray = new JSONArray(); - for (NavDrawerItem item : items) { - JSONObject obj = new JSONObject(); - obj.put(NavDrawerItem.NAME_KEY, item.name); - obj.put(NavDrawerItem.URI_KEY, item.uri); - obj.put(NavDrawerItem.ICON_NAME_KEY, item.iconName); - obj.put(NavDrawerItem.FLAGS_KEY, item.flags); - jArray.put(obj); - } - JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); - allItems.put(appPackage, jArray); - app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - private Map> getNavDrawerItems() { - Map> res = new LinkedHashMap<>(); - try { - JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); - for (Iterator it = allItems.keys(); it.hasNext(); ) { - String appPackage = (String) it.next(); - JSONArray jArray = allItems.getJSONArray(appPackage); - List list = new ArrayList<>(); - for (int i = 0; i < jArray.length(); i++) { - JSONObject obj = jArray.getJSONObject(i); - list.add(new NavDrawerItem( - obj.optString(NavDrawerItem.NAME_KEY), - obj.optString(NavDrawerItem.URI_KEY), - obj.optString(NavDrawerItem.ICON_NAME_KEY), - obj.optInt(NavDrawerItem.FLAGS_KEY, -1) - )); - } - res.put(appPackage, list); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return res; + app.getAppCustomization().registerNavDrawerItems(activity, adapter); } public List getConnectedApps() { @@ -2062,6 +1944,15 @@ public class OsmandAidlApi { } } + boolean areOsmandSettingsCustomized(String sharedPreferencesName) { + return app.getAppCustomization().areSettingsCustomizedForPreference(sharedPreferencesName); + } + + boolean setCustomization(CustomizationInfoParams params) { + app.getAppCustomization().setCustomization(params); + return true; + } + private void addContextMenuButtonListener(ContextMenuButtonsParams buttonsParams, long callbackId) { IContextMenuButtonListener listener = new IContextMenuButtonListener() { @@ -2325,30 +2216,6 @@ public class OsmandAidlApi { } } - private static class NavDrawerItem { - - static final String NAME_KEY = "name"; - static final String URI_KEY = "uri"; - static final String ICON_NAME_KEY = "icon_name"; - static final String FLAGS_KEY = "flags"; - - private String name; - private String uri; - private String iconName; - private int flags; - - NavDrawerItem(String name, String uri, String iconName, int flags) { - this.name = name; - this.uri = uri; - this.iconName = iconName; - this.flags = flags; - } - - public String getId() { - return DRAWER_ITEM_ID_SCHEME + name; - } - } - public interface SearchCompleteCallback { void onSearchComplete(List resultSet); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java index 0d6259ae65..3260e1ef2d 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlService.java @@ -10,7 +10,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.support.annotation.Nullable; -import java.util.concurrent.ConcurrentHashMap; import net.osmand.PlatformUtil; import net.osmand.aidl.OsmandAidlApi.GpxBitmapCreatedCallback; import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback; @@ -19,6 +18,9 @@ import net.osmand.aidl.calculateroute.CalculateRouteParams; import net.osmand.aidl.contextmenu.ContextMenuButtonsParams; import net.osmand.aidl.contextmenu.RemoveContextMenuButtonsParams; import net.osmand.aidl.contextmenu.UpdateContextMenuButtonsParams; +import net.osmand.aidl.copyfile.CopyFileParams; +import net.osmand.aidl.customization.CustomizationInfoParams; +import net.osmand.aidl.customization.OsmandSettingsInfoParams; import net.osmand.aidl.customization.OsmandSettingsParams; import net.osmand.aidl.customization.SetWidgetsParams; import net.osmand.aidl.favorite.AddFavoriteParams; @@ -71,7 +73,6 @@ import net.osmand.aidl.plugins.PluginParams; import net.osmand.aidl.search.SearchParams; import net.osmand.aidl.search.SearchResult; import net.osmand.aidl.tiles.ASqliteDbFile; -import net.osmand.aidl.copyfile.CopyFileParams; import net.osmand.plus.OsmandApplication; import net.osmand.util.Algorithms; @@ -80,6 +81,7 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import static net.osmand.aidl.OsmandAidlConstants.CANNOT_ACCESS_API_ERROR; @@ -131,7 +133,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { public void onCreate() { super.onCreate(); OsmandAidlApi api = getApi("setting_listener"); - if(api != null) { + if (api != null) { api.aidlCallbackListener = this; } } @@ -142,7 +144,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { callbacks.clear(); OsmandAidlApi api = getApi("clear_listener"); - if(api != null) { + if (api != null) { api.aidlCallbackListener = null; } mHandlerThread.quit(); @@ -1044,7 +1046,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { public long registerForNavigationUpdates(ANavigationUpdateParams params, final IOsmAndAidlCallback callback) { try { OsmandAidlApi api = getApi("registerForNavUpdates"); - if (api != null ) { + if (api != null) { if (!params.isSubscribeToUpdates() && params.getCallbackId() != -1) { api.unregisterFromUpdates(params.getCallbackId()); removeAidlCallback(params.getCallbackId()); @@ -1113,6 +1115,28 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { return false; } } + + @Override + public boolean areOsmandSettingsCustomized(OsmandSettingsInfoParams params) { + try { + OsmandAidlApi api = getApi("areOsmandSettingsCustomized"); + return api != null && api.areOsmandSettingsCustomized(params.getSharedPreferencesName()); + } catch (Exception e) { + handleException(e); + return false; + } + } + + @Override + public boolean setCustomization(CustomizationInfoParams params) { + try { + OsmandAidlApi api = getApi("setCustomization"); + return api != null && params != null && api.setCustomization(params); + } catch (Exception e) { + handleException(e); + return false; + } + } }; public static class AidlCallbackParams { @@ -1141,6 +1165,4 @@ public class OsmandAidlService extends Service implements AidlCallbackListener { this.key = key; } } - - -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.aidl b/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.aidl new file mode 100644 index 0000000000..e72d2d47dc --- /dev/null +++ b/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidl.customization; + +parcelable CustomizationInfoParams; \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.java b/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.java new file mode 100644 index 0000000000..0e83f7f41c --- /dev/null +++ b/OsmAnd/src/net/osmand/aidl/customization/CustomizationInfoParams.java @@ -0,0 +1,172 @@ +package net.osmand.aidl.customization; + +import android.annotation.SuppressLint; +import android.os.Parcel; +import android.os.Parcelable; + +import net.osmand.aidl.navdrawer.NavDrawerFooterParams; +import net.osmand.aidl.navdrawer.NavDrawerHeaderParams; +import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams; +import net.osmand.aidl.plugins.PluginParams; + +import java.util.ArrayList; +import java.util.List; + +public class CustomizationInfoParams implements Parcelable { + + private OsmandSettingsParams settingsParams; + + private NavDrawerHeaderParams navDrawerHeaderParams; + private NavDrawerFooterParams navDrawerFooterParams; + private SetNavDrawerItemsParams navDrawerItemsParams; + + private ArrayList visibilityWidgetsParams = new ArrayList<>(); + private ArrayList availabilityWidgetsParams = new ArrayList<>(); + + private ArrayList pluginsParams = new ArrayList<>(); + + private List featuresEnabledIds = new ArrayList<>(); + private List featuresDisabledIds = new ArrayList<>(); + private List featuresEnabledPatterns = new ArrayList<>(); + private List featuresDisabledPatterns = new ArrayList<>(); + + public CustomizationInfoParams(OsmandSettingsParams settingsParams, + NavDrawerHeaderParams navDrawerHeaderParams, + NavDrawerFooterParams navDrawerFooterParams, + SetNavDrawerItemsParams navDrawerItemsParams, + ArrayList visibilityWidgetsParams, + ArrayList availabilityWidgetsParams, + ArrayList pluginsParams, + List featuresEnabledIds, + List featuresDisabledIds, + List featuresEnabledPatterns, + List featuresDisabledPatterns) { + this.settingsParams = settingsParams; + this.navDrawerHeaderParams = navDrawerHeaderParams; + this.navDrawerFooterParams = navDrawerFooterParams; + this.navDrawerItemsParams = navDrawerItemsParams; + + if (visibilityWidgetsParams != null) { + this.visibilityWidgetsParams.addAll(visibilityWidgetsParams); + } + if (availabilityWidgetsParams != null) { + this.availabilityWidgetsParams.addAll(availabilityWidgetsParams); + } + if (pluginsParams != null) { + this.pluginsParams.addAll(pluginsParams); + } + if (featuresEnabledIds != null) { + this.featuresEnabledIds.addAll(featuresEnabledIds); + } + if (featuresDisabledIds != null) { + this.featuresDisabledIds.addAll(featuresDisabledIds); + } + if (featuresEnabledPatterns != null) { + this.featuresEnabledPatterns.addAll(featuresEnabledPatterns); + } + if (featuresDisabledPatterns != null) { + this.featuresDisabledPatterns.addAll(featuresDisabledPatterns); + } + } + + public CustomizationInfoParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public CustomizationInfoParams createFromParcel(Parcel in) { + return new CustomizationInfoParams(in); + } + + @Override + public CustomizationInfoParams[] newArray(int size) { + return new CustomizationInfoParams[size]; + } + }; + + public OsmandSettingsParams getSettingsParams() { + return settingsParams; + } + + public NavDrawerHeaderParams getNavDrawerHeaderParams() { + return navDrawerHeaderParams; + } + + public NavDrawerFooterParams getNavDrawerFooterParams() { + return navDrawerFooterParams; + } + + public SetNavDrawerItemsParams getNavDrawerItemsParams() { + return navDrawerItemsParams; + } + + public ArrayList getVisibilityWidgetsParams() { + return visibilityWidgetsParams; + } + + public ArrayList getAvailabilityWidgetsParams() { + return availabilityWidgetsParams; + } + + public ArrayList getPluginsParams() { + return pluginsParams; + } + + public List getFeaturesEnabledIds() { + return featuresEnabledIds; + } + + public List getFeaturesDisabledIds() { + return featuresDisabledIds; + } + + public List getFeaturesEnabledPatterns() { + return featuresEnabledPatterns; + } + + public List getFeaturesDisabledPatterns() { + return featuresDisabledPatterns; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeParcelable(settingsParams, flags); + + out.writeParcelable(navDrawerHeaderParams, flags); + out.writeParcelable(navDrawerFooterParams, flags); + out.writeParcelable(navDrawerItemsParams, flags); + + out.writeTypedList(visibilityWidgetsParams); + out.writeTypedList(availabilityWidgetsParams); + out.writeTypedList(pluginsParams); + + out.writeStringList(featuresEnabledIds); + out.writeStringList(featuresDisabledIds); + out.writeStringList(featuresEnabledPatterns); + out.writeStringList(featuresDisabledPatterns); + } + + @SuppressLint("ParcelClassLoader") + private void readFromParcel(Parcel in) { + settingsParams = in.readParcelable(OsmandSettingsParams.class.getClassLoader()); + + navDrawerHeaderParams = in.readParcelable(NavDrawerHeaderParams.class.getClassLoader()); + navDrawerFooterParams = in.readParcelable(NavDrawerFooterParams.class.getClassLoader()); + navDrawerItemsParams = in.readParcelable(SetNavDrawerItemsParams.class.getClassLoader()); + + in.readTypedList(visibilityWidgetsParams, SetWidgetsParams.CREATOR); + in.readTypedList(availabilityWidgetsParams, SetWidgetsParams.CREATOR); + in.readTypedList(pluginsParams, PluginParams.CREATOR); + + in.readStringList(featuresEnabledIds); + in.readStringList(featuresDisabledIds); + in.readStringList(featuresEnabledPatterns); + in.readStringList(featuresDisabledPatterns); + } + + @Override + public int describeContents() { + return 0; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.aidl b/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.aidl new file mode 100644 index 0000000000..80d0fa56ed --- /dev/null +++ b/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidl.customization; + +parcelable OsmandSettingsInfoParams; \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.java b/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.java new file mode 100644 index 0000000000..ba4285af1d --- /dev/null +++ b/OsmAnd/src/net/osmand/aidl/customization/OsmandSettingsInfoParams.java @@ -0,0 +1,50 @@ +package net.osmand.aidl.customization; + +import android.annotation.SuppressLint; +import android.os.Parcel; +import android.os.Parcelable; +import android.support.annotation.NonNull; + +public class OsmandSettingsInfoParams implements Parcelable { + + private String sharedPreferencesName; + + public OsmandSettingsInfoParams(@NonNull String sharedPreferencesName) { + this.sharedPreferencesName = sharedPreferencesName; + } + + public OsmandSettingsInfoParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public OsmandSettingsInfoParams createFromParcel(Parcel in) { + return new OsmandSettingsInfoParams(in); + } + + @Override + public OsmandSettingsInfoParams[] newArray(int size) { + return new OsmandSettingsInfoParams[size]; + } + }; + + public String getSharedPreferencesName() { + return sharedPreferencesName; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(sharedPreferencesName); + } + + @SuppressLint("ParcelClassLoader") + private void readFromParcel(Parcel in) { + sharedPreferencesName = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/OsmAndAppCustomization.java b/OsmAnd/src/net/osmand/plus/OsmAndAppCustomization.java index a47ca5dade..8c8a26f542 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndAppCustomization.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndAppCustomization.java @@ -1,8 +1,8 @@ package net.osmand.plus; -import static net.osmand.plus.osmedit.OpenstreetmapLocalUtil.LOG; - import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; @@ -11,11 +11,16 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; +import android.widget.ArrayAdapter; import net.osmand.IProgress; import net.osmand.IndexConstants; +import net.osmand.aidl.customization.CustomizationInfoParams; +import net.osmand.aidl.customization.OsmandSettingsParams; +import net.osmand.aidl.customization.SetWidgetsParams; import net.osmand.aidl.navdrawer.NavDrawerFooterParams; import net.osmand.aidl.navdrawer.NavDrawerHeaderParams; +import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams; import net.osmand.aidl.plugins.PluginParams; import net.osmand.data.LocationPoint; import net.osmand.plus.activities.MapActivity; @@ -28,6 +33,10 @@ import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.views.OsmandMapTileView; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -36,13 +45,18 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import static net.osmand.plus.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME; + public class OsmAndAppCustomization { + private static final int MAX_NAV_DRAWER_ITEMS_PER_APP = 3; + protected OsmandApplication app; protected OsmandSettings osmandSettings; @@ -209,7 +223,9 @@ public class OsmAndAppCustomization { } @Nullable - public ArrayList getNavDrawerLogoParams() {return navDrawerParams; } + public ArrayList getNavDrawerLogoParams() { + return navDrawerParams; + } public boolean setNavDrawerLogo(String uri, @Nullable String packageName, @Nullable String intent) { if (TextUtils.isEmpty(uri)) { @@ -283,6 +299,89 @@ public class OsmAndAppCustomization { return set; } + public void regWidgetsVisibility(@NonNull ArrayList visibilityWidgetsParams) { + for (SetWidgetsParams setWidgetsParams : visibilityWidgetsParams) { + regWidgetVisibility(setWidgetsParams.getWidgetKey(), setWidgetsParams.getAppModesKeys()); + } + } + + public void regWidgetsAvailability(@NonNull ArrayList availabilityWidgetsParams) { + for (SetWidgetsParams setWidgetsParams : availabilityWidgetsParams) { + regWidgetAvailability(setWidgetsParams.getWidgetKey(), setWidgetsParams.getAppModesKeys()); + } + } + + public void setCustomization(CustomizationInfoParams params) { + OsmandSettingsParams settingsParams = params.getSettingsParams(); + if (settingsParams != null) { + customizeOsmandSettings(settingsParams.getSharedPreferencesName(), settingsParams.getBundle()); + } + NavDrawerHeaderParams navDrawerHeaderParams = params.getNavDrawerHeaderParams(); + NavDrawerFooterParams navDrawerFooterParams = params.getNavDrawerFooterParams(); + SetNavDrawerItemsParams navDrawerItemsParams = params.getNavDrawerItemsParams(); + + setNavDrawerParams(navDrawerHeaderParams, navDrawerFooterParams, navDrawerItemsParams); + + ArrayList visibilityWidgetsParams = params.getVisibilityWidgetsParams(); + ArrayList availabilityWidgetsParams = params.getAvailabilityWidgetsParams(); + + setWidgetsParams(visibilityWidgetsParams, availabilityWidgetsParams); + + ArrayList pluginsParams = params.getPluginsParams(); + if (pluginsParams != null) { + changePluginsStatus(pluginsParams); + } + + List enabledIds = params.getFeaturesEnabledIds(); + List disabledIds = params.getFeaturesDisabledIds(); + + setFeaturesIds(enabledIds, disabledIds); + + List enabledPatterns = params.getFeaturesEnabledPatterns(); + List disabledPatterns = params.getFeaturesDisabledPatterns(); + + setFeaturesPatterns(enabledPatterns, disabledPatterns); + } + + public void setNavDrawerParams(NavDrawerHeaderParams navDrawerHeaderParams, NavDrawerFooterParams navDrawerFooterParams, SetNavDrawerItemsParams navDrawerItemsParams) { + if (navDrawerHeaderParams != null) { + setNavDrawerLogoWithParams(navDrawerHeaderParams.getImageUri(), navDrawerHeaderParams.getPackageName(), navDrawerHeaderParams.getIntent()); + } + if (navDrawerFooterParams != null) { + setNavDrawerFooterParams(navDrawerFooterParams); + } + if (navDrawerItemsParams != null) { + setNavDrawerItems(navDrawerItemsParams.getAppPackage(), navDrawerItemsParams.getItems()); + } + } + + public void setWidgetsParams(ArrayList visibilityWidgetsParams, ArrayList availabilityWidgetsParams) { + if (visibilityWidgetsParams != null) { + regWidgetsVisibility(visibilityWidgetsParams); + } + if (availabilityWidgetsParams != null) { + regWidgetsAvailability(availabilityWidgetsParams); + } + } + + public void setFeaturesIds(List enabledIds, List disabledIds) { + if (enabledIds != null) { + setFeaturesEnabledIds(enabledIds); + } + if (disabledIds != null) { + setFeaturesDisabledIds(disabledIds); + } + } + + public void setFeaturesPatterns(List enabledPatterns, List disabledPatterns) { + if (enabledPatterns != null) { + setFeaturesEnabledPatterns(enabledPatterns); + } + if (disabledPatterns != null) { + setFeaturesDisabledPatterns(disabledPatterns); + } + } + public boolean isWidgetVisible(@NonNull String key, ApplicationMode appMode) { Set set = widgetsVisibilityMap.get(key); if (set == null) { @@ -300,10 +399,16 @@ public class OsmAndAppCustomization { } public boolean setNavDrawerLogoWithParams(String imageUri, @Nullable String packageName, - @Nullable String intent) { + @Nullable String intent) { return setNavDrawerLogo(imageUri, packageName, intent); } + public void changePluginsStatus(List pluginsParams) { + for (PluginParams pluginParams : pluginsParams) { + changePluginStatus(pluginParams); + } + } + public boolean changePluginStatus(PluginParams params) { if (params.getNewState() == 0) { for (OsmandPlugin plugin : OsmandPlugin.getEnabledPlugins()) { @@ -326,6 +431,126 @@ public class OsmAndAppCustomization { return false; } + public boolean setNavDrawerItems(String appPackage, List items) { + if (!TextUtils.isEmpty(appPackage) && items != null) { + clearNavDrawerItems(appPackage); + if (items.isEmpty()) { + return true; + } + List newItems = new ArrayList<>(MAX_NAV_DRAWER_ITEMS_PER_APP); + boolean success = true; + for (int i = 0; i < items.size() && i <= MAX_NAV_DRAWER_ITEMS_PER_APP; i++) { + net.osmand.aidl.navdrawer.NavDrawerItem item = items.get(i); + String name = item.getName(); + String uri = item.getUri(); + if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(uri)) { + newItems.add(new NavDrawerItem(name, uri, item.getIconName(), item.getFlags())); + } else { + success = false; + break; + } + } + if (success) { + saveNavDrawerItems(appPackage, newItems); + } + return success; + } + return false; + } + + private void clearNavDrawerItems(String appPackage) { + try { + JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); + allItems.put(appPackage, new JSONArray()); + app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + private void saveNavDrawerItems(String appPackage, List items) { + try { + JSONArray jArray = new JSONArray(); + for (NavDrawerItem item : items) { + JSONObject obj = new JSONObject(); + obj.put(NavDrawerItem.NAME_KEY, item.name); + obj.put(NavDrawerItem.URI_KEY, item.uri); + obj.put(NavDrawerItem.ICON_NAME_KEY, item.iconName); + obj.put(NavDrawerItem.FLAGS_KEY, item.flags); + jArray.put(obj); + } + JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); + allItems.put(appPackage, jArray); + app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public void registerNavDrawerItems(final Activity activity, ContextMenuAdapter adapter) { + PackageManager pm = activity.getPackageManager(); + for (Map.Entry> entry : getNavDrawerItems().entrySet()) { + String appPackage = entry.getKey(); + for (NavDrawerItem item : entry.getValue()) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.uri)); + if (intent.resolveActivity(pm) == null) { + intent = pm.getLaunchIntentForPackage(appPackage); + } + if (intent != null) { + if (item.flags != -1) { + intent.addFlags(item.flags); + } + final Intent finalIntent = intent; + adapter.addItem(new ContextMenuItem.ItemBuilder() + .setId(item.getId()) + .setTitle(item.name) + .setIcon(getIconId(item.iconName)) + .setListener(new ContextMenuAdapter.ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) { + activity.startActivity(finalIntent); + return true; + } + }) + .createItem()); + } + } + } + } + + private Map> getNavDrawerItems() { + Map> res = new LinkedHashMap<>(); + try { + JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get()); + for (Iterator it = allItems.keys(); it.hasNext(); ) { + String appPackage = (String) it.next(); + JSONArray jArray = allItems.getJSONArray(appPackage); + List list = new ArrayList<>(); + for (int i = 0; i < jArray.length(); i++) { + JSONObject obj = jArray.getJSONObject(i); + list.add(new NavDrawerItem( + obj.optString(NavDrawerItem.NAME_KEY), + obj.optString(NavDrawerItem.URI_KEY), + obj.optString(NavDrawerItem.ICON_NAME_KEY), + obj.optInt(NavDrawerItem.FLAGS_KEY, -1) + )); + } + res.put(appPackage, list); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return res; + } + + private int getIconId(@Nullable String iconName) { + if (!TextUtils.isEmpty(iconName)) { + int id = app.getResources().getIdentifier(iconName, "drawable", app.getPackageName()); + return id == 0 ? -1 : id; + } + return -1; + } + @NonNull private HashSet getAppModesSet(@Nullable List appModeKeys) { HashSet set = new HashSet<>(); @@ -365,10 +590,29 @@ public class OsmAndAppCustomization { return !isMatchesPattern(id, featuresDisabledPatterns); } + public boolean isOsmandCustomized() { + return areWidgetsCustomized() || areFeaturesCustomized() || areSettingsCustomized(); + } + public boolean areWidgetsCustomized() { return widgetsCustomized; } + public boolean areFeaturesCustomized() { + return featuresCustomized; + } + + public boolean areSettingsCustomized() { + return customOsmandSettings != null; + } + + public boolean areSettingsCustomizedForPreference(String sharedPreferencesName) { + if (customOsmandSettings != null && customOsmandSettings.sharedPreferencesName.equals(sharedPreferencesName)) { + return true; + } + return OsmandSettings.areSettingsCustomizedForPreference(sharedPreferencesName, app); + } + private void setFeaturesCustomized() { featuresCustomized = true; } @@ -405,4 +649,28 @@ public class OsmAndAppCustomization { public void removeListener(OsmAndAppCustomizationListener listener) { this.listeners.remove(listener); } -} + + private static class NavDrawerItem { + + static final String NAME_KEY = "name"; + static final String URI_KEY = "uri"; + static final String ICON_NAME_KEY = "icon_name"; + static final String FLAGS_KEY = "flags"; + + private String name; + private String uri; + private String iconName; + private int flags; + + NavDrawerItem(String name, String uri, String iconName, int flags) { + this.name = name; + this.uri = uri; + this.iconName = iconName; + this.flags = flags; + } + + public String getId() { + return DRAWER_ITEM_ID_SCHEME + name; + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index dde6144c54..3c513469ab 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -4,6 +4,7 @@ package net.osmand.plus; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.hardware.Sensor; import android.hardware.SensorManager; @@ -28,6 +29,7 @@ import net.osmand.plus.access.AccessibilityMode; import net.osmand.plus.access.RelativeDirectionStyle; import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.api.SettingsAPI.SettingsEditor; +import net.osmand.plus.api.SettingsAPIImpl; import net.osmand.plus.dialogs.RateUsBottomSheetDialog; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.mapillary.MapillaryPlugin; @@ -120,6 +122,7 @@ public class OsmandSettings { } // These settings are stored in SharedPreferences + private static final String CUSTOM_SHARED_PREFERENCES_PREFIX = "net.osmand.customsettings."; private static final String SHARED_PREFERENCES_NAME = "net.osmand.settings"; private static String CUSTOM_SHARED_PREFERENCES_NAME; @@ -148,8 +151,9 @@ public class OsmandSettings { protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI, String sharedPreferencesName) { ctx = clientContext; this.settingsAPI = settinsAPI; - CUSTOM_SHARED_PREFERENCES_NAME = "net.osmand.customsettings." + sharedPreferencesName; + CUSTOM_SHARED_PREFERENCES_NAME = CUSTOM_SHARED_PREFERENCES_PREFIX + sharedPreferencesName; initPrefs(); + setCustomized(); } private void initPrefs() { @@ -160,6 +164,12 @@ public class OsmandSettings { registeredPreferences.put(APPLICATION_MODE.getId(), APPLICATION_MODE); } + private static final String SETTING_CUSTOMIZED_ID = "settings_customized"; + + private void setCustomized() { + settingsAPI.edit(globalPreferences).putBoolean(SETTING_CUSTOMIZED_ID, true).commit(); + } + public OsmandApplication getContext() { return ctx; } @@ -182,6 +192,14 @@ public class OsmandSettings { } } + public static boolean areSettingsCustomizedForPreference(String sharedPreferencesName, OsmandApplication app) { + String customPrefName = CUSTOM_SHARED_PREFERENCES_PREFIX + sharedPreferencesName; + SettingsAPIImpl settingsAPI = new net.osmand.plus.api.SettingsAPIImpl(app); + SharedPreferences globalPreferences = (SharedPreferences) settingsAPI.getPreferenceObject(customPrefName); + + return globalPreferences != null && globalPreferences.getBoolean(SETTING_CUSTOMIZED_ID, false); + } + public Object getProfilePreferences(ApplicationMode mode) { return settingsAPI.getPreferenceObject(getSharedPreferencesName(mode)); }