Android Open Source - muzei Source Manager






From Project

Back to project page muzei.

License

The source code is released under:

Apache License

If you think the Android project muzei listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2014 Google Inc./*  ww  w.j av  a  2s .  co  m*/
 *
 * 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.google.android.apps.muzei;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.text.TextUtils;

import com.google.android.apps.muzei.api.internal.SourceState;
import com.google.android.apps.muzei.event.SelectedSourceChangedEvent;
import com.google.android.apps.muzei.event.SelectedSourceStateChangedEvent;
import com.google.android.apps.muzei.featuredart.FeaturedArtSource;
import com.google.android.apps.muzei.util.LogUtil;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import de.greenrobot.event.EventBus;

import static com.google.android.apps.muzei.api.internal.ProtocolConstants.ACTION_HANDLE_COMMAND;
import static com.google.android.apps.muzei.api.internal.ProtocolConstants.ACTION_NETWORK_AVAILABLE;
import static com.google.android.apps.muzei.api.internal.ProtocolConstants.ACTION_SUBSCRIBE;
import static com.google.android.apps.muzei.api.internal.ProtocolConstants.EXTRA_COMMAND_ID;
import static com.google.android.apps.muzei.api.internal.ProtocolConstants.EXTRA_SUBSCRIBER_COMPONENT;
import static com.google.android.apps.muzei.api.internal.ProtocolConstants.EXTRA_TOKEN;
import static com.google.android.apps.muzei.util.LogUtil.LOGD;
import static com.google.android.apps.muzei.util.LogUtil.LOGE;
import static com.google.android.apps.muzei.util.LogUtil.LOGW;

/**
 * Thread-safe.
 */
public class SourceManager {
    private static final String TAG = LogUtil.makeLogTag(SourceManager.class);
    private static final String PREF_SELECTED_SOURCE = "selected_source";
    private static final String PREF_SELECTED_SOURCE_TOKEN = "selected_source_token";
    private static final String PREF_SOURCE_STATES = "source_states";

    private Context mApplicationContext;
    private ComponentName mSubscriberComponentName;
    private SharedPreferences mSharedPrefs;

    private ComponentName mSelectedSource;
    private String mSelectedSourceToken;
    private Map<ComponentName, SourceState> mSourceStates = new HashMap<>();

    private static SourceManager sInstance;

    public static SourceManager getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new SourceManager(context);
        }

        return sInstance;
    }

    private SourceManager(Context context) {
        mApplicationContext = context.getApplicationContext();
        mSubscriberComponentName = new ComponentName(context, SourceSubscriberService.class);
        mSharedPrefs = context.getSharedPreferences("muzei_art_sources", 0);
        loadStoredData();
    }

    private void loadStoredData() {
        // Load selected source info
        String selectedSource = mSharedPrefs.getString(PREF_SELECTED_SOURCE, null);
        if (selectedSource != null) {
            mSelectedSource = ComponentName.unflattenFromString(selectedSource);
        } else {
            selectDefaultSource();
            return;
        }

        mSelectedSourceToken = mSharedPrefs.getString(PREF_SELECTED_SOURCE_TOKEN, null);

        // Load current source states
        Set<String> sourceStates = mSharedPrefs.getStringSet(PREF_SOURCE_STATES, null);
        mSourceStates.clear();
        if (sourceStates != null) {
            for (String sourceStatesPair : sourceStates) {
                String[] pair = sourceStatesPair.split("\\|", 2);
                try {
                    mSourceStates.put(
                            ComponentName.unflattenFromString(pair[0]),
                            SourceState.fromJson(
                                    (JSONObject) new JSONTokener(pair[1]).nextValue()));
                } catch (JSONException e) {
                    LOGE(TAG, "Error loading source state.", e);
                }
            }
        }
    }

    public void selectDefaultSource() {
        selectSource(new ComponentName(mApplicationContext, FeaturedArtSource.class));
    }

    public void selectSource(ComponentName source) {
        if (source == null) {
            LOGE(TAG, "selectSource: Empty source");
            return;
        }

        synchronized (this) {
            if (source.equals(mSelectedSource)) {
                return;
            }

            LOGD(TAG, "Source " + source + " selected.");

            if (mSelectedSource != null) {
                // unsubscribe from existing source
                mApplicationContext.startService(new Intent(ACTION_SUBSCRIBE)
                        .setComponent(mSelectedSource)
                        .putExtra(EXTRA_SUBSCRIBER_COMPONENT, mSubscriberComponentName)
                        .putExtra(EXTRA_TOKEN, (String) null));
            }

            // generate a new token and subscribe to new source
            mSelectedSource = source;
            mSelectedSourceToken = UUID.randomUUID().toString();
            mSharedPrefs.edit()
                    .putString(PREF_SELECTED_SOURCE, source.flattenToShortString())
                    .putString(PREF_SELECTED_SOURCE_TOKEN, mSelectedSourceToken)
                    .apply();

            subscribeToSelectedSource();
        }

        EventBus.getDefault().post(new SelectedSourceChangedEvent());
        EventBus.getDefault().post(new SelectedSourceStateChangedEvent());
    }

    public void handlePublishState(String token, SourceState state) {
        synchronized (this) {
            if (!TextUtils.equals(token, mSelectedSourceToken)) {
                LOGW(TAG, "Dropping update from non-selected source (token mismatch).");
                return;
            }

            if (state == null) {
                mSourceStates.remove(mSelectedSource);
            } else {
                mSourceStates.put(mSelectedSource, state);
            }

            try {
                StringBuilder sb = new StringBuilder();
                Set<String> sourceStates = new HashSet<>();
                for (ComponentName source : mSourceStates.keySet()) {
                    SourceState sourceState = mSourceStates.get(source);
                    if (sourceState == null) {
                        continue;
                    }

                    sb.setLength(0);
                    sb.append(source.flattenToShortString())
                            .append("|")
                            .append(sourceState.toJson().toString());
                    sourceStates.add(sb.toString());
                }

                mSharedPrefs.edit().putStringSet(PREF_SOURCE_STATES, sourceStates).apply();
            } catch (JSONException e) {
                LOGE(TAG, "Error storing source status data.", e);
            }
        }

        EventBus.getDefault().post(new SelectedSourceStateChangedEvent());
    }

    public synchronized ComponentName getSelectedSource() {
        return mSelectedSource;
    }

    public synchronized SourceState getSourceState(ComponentName source) {
        return mSourceStates.get(source);
    }

    public synchronized SourceState getSelectedSourceState() {
        return mSourceStates.get(mSelectedSource);
    }

    public synchronized void sendAction(int id) {
        if (mSelectedSource != null) {
            mApplicationContext.startService(new Intent(ACTION_HANDLE_COMMAND)
                    .setComponent(mSelectedSource)
                    .putExtra(EXTRA_COMMAND_ID, id));
        }
    }

    public synchronized void subscribeToSelectedSource() {
        if (mSelectedSource != null) {
            mApplicationContext.startService(new Intent(ACTION_SUBSCRIBE)
                    .setComponent(mSelectedSource)
                    .putExtra(EXTRA_SUBSCRIBER_COMPONENT, mSubscriberComponentName)
                    .putExtra(EXTRA_TOKEN, mSelectedSourceToken));
        }
    }

    public synchronized void maybeDispatchNetworkAvailable() {
        SourceState state = getSelectedSourceState();
        if (state != null && state.getWantsNetworkAvailable()) {
            mApplicationContext.startService(new Intent(ACTION_NETWORK_AVAILABLE)
                    .setComponent(mSelectedSource)
                    .putExtra(EXTRA_SUBSCRIBER_COMPONENT, mSubscriberComponentName)
                    .putExtra(EXTRA_TOKEN, mSelectedSourceToken));
        }
    }
}




Java Source Code List

com.example.muzei.examplecontractwidget.ArtworkUpdateReceiver.java
com.example.muzei.examplecontractwidget.ArtworkUpdateService.java
com.example.muzei.examplecontractwidget.MuzeiAppWidgetProvider.java
com.example.muzei.examplesource500px.Config.java
com.example.muzei.examplesource500px.FiveHundredPxExampleArtSource.java
com.example.muzei.examplesource500px.FiveHundredPxService.java
com.example.muzei.watchface.ArtworkImageLoader.java
com.example.muzei.watchface.MuzeiExampleWatchface.java
com.example.muzei.watchface.WatchfaceArtworkImageLoader.java
com.google.android.apps.muzei.ActivateMuzeiIntentService.java
com.google.android.apps.muzei.ArtDetailViewport.java
com.google.android.apps.muzei.ArtworkCacheIntentService.java
com.google.android.apps.muzei.ArtworkCache.java
com.google.android.apps.muzei.FullScreenActivity.java
com.google.android.apps.muzei.LockScreenVisibleReceiver.java
com.google.android.apps.muzei.MuzeiActivity.java
com.google.android.apps.muzei.MuzeiApplication.java
com.google.android.apps.muzei.MuzeiWallpaperService.java
com.google.android.apps.muzei.MuzeiWatchFace.java
com.google.android.apps.muzei.MuzeiWearableListenerService.java
com.google.android.apps.muzei.MuzeiWearableListenerService.java
com.google.android.apps.muzei.NetworkChangeReceiver.java
com.google.android.apps.muzei.NewWallpaperNotificationReceiver.java
com.google.android.apps.muzei.PhotoSetAsTargetActivity.java
com.google.android.apps.muzei.SourceManager.java
com.google.android.apps.muzei.SourcePackageChangeReceiver.java
com.google.android.apps.muzei.SourceSubscriberService.java
com.google.android.apps.muzei.TaskQueueService.java
com.google.android.apps.muzei.WearableController.java
com.google.android.apps.muzei.api.Artwork.java
com.google.android.apps.muzei.api.MuzeiArtSource.java
com.google.android.apps.muzei.api.MuzeiContract.java
com.google.android.apps.muzei.api.RemoteMuzeiArtSource.java
com.google.android.apps.muzei.api.UserCommand.java
com.google.android.apps.muzei.api.internal.ProtocolConstants.java
com.google.android.apps.muzei.api.internal.SourceState.java
com.google.android.apps.muzei.event.ArtDetailOpenedClosedEvent.java
com.google.android.apps.muzei.event.ArtworkLoadingStateChangedEvent.java
com.google.android.apps.muzei.event.ArtworkSizeChangedEvent.java
com.google.android.apps.muzei.event.BlurAmountChangedEvent.java
com.google.android.apps.muzei.event.CurrentArtworkDownloadedEvent.java
com.google.android.apps.muzei.event.DimAmountChangedEvent.java
com.google.android.apps.muzei.event.GainedNetworkConnectivityEvent.java
com.google.android.apps.muzei.event.GalleryChosenUrisChangedEvent.java
com.google.android.apps.muzei.event.GreyAmountChangedEvent.java
com.google.android.apps.muzei.event.LockScreenVisibleChangedEvent.java
com.google.android.apps.muzei.event.SelectedSourceChangedEvent.java
com.google.android.apps.muzei.event.SelectedSourceStateChangedEvent.java
com.google.android.apps.muzei.event.SwitchingPhotosStateChangedEvent.java
com.google.android.apps.muzei.event.WallpaperActiveStateChangedEvent.java
com.google.android.apps.muzei.event.WallpaperSizeChangedEvent.java
com.google.android.apps.muzei.featuredart.FeaturedArtSource.java
com.google.android.apps.muzei.gallery.GalleryArtSource.java
com.google.android.apps.muzei.gallery.GalleryDatabase.java
com.google.android.apps.muzei.gallery.GalleryEmptyStateGraphicView.java
com.google.android.apps.muzei.gallery.GallerySettingsActivity.java
com.google.android.apps.muzei.gallery.GalleryStore.java
com.google.android.apps.muzei.provider.MuzeiProvider.java
com.google.android.apps.muzei.render.BitmapRegionLoader.java
com.google.android.apps.muzei.render.DemoRenderController.java
com.google.android.apps.muzei.render.GLColorOverlay.java
com.google.android.apps.muzei.render.GLPicture.java
com.google.android.apps.muzei.render.GLTextureView.java
com.google.android.apps.muzei.render.GLUtil.java
com.google.android.apps.muzei.render.ImageUtil.java
com.google.android.apps.muzei.render.MuzeiBlurRenderer.java
com.google.android.apps.muzei.render.MuzeiRendererFragment.java
com.google.android.apps.muzei.render.RealRenderController.java
com.google.android.apps.muzei.render.RenderController.java
com.google.android.apps.muzei.settings.AboutActivity.java
com.google.android.apps.muzei.settings.Prefs.java
com.google.android.apps.muzei.settings.SettingsActivity.java
com.google.android.apps.muzei.settings.SettingsAdvancedFragment.java
com.google.android.apps.muzei.settings.SettingsChooseSourceFragment.java
com.google.android.apps.muzei.util.AnimatedMuzeiLoadingSpinnerView.java
com.google.android.apps.muzei.util.AnimatedMuzeiLogoFragment.java
com.google.android.apps.muzei.util.AnimatedMuzeiLogoView.java
com.google.android.apps.muzei.util.CheatSheet.java
com.google.android.apps.muzei.util.DrawInsetsFrameLayout.java
com.google.android.apps.muzei.util.IOUtil.java
com.google.android.apps.muzei.util.ImageBlurrer.java
com.google.android.apps.muzei.util.LogUtil.java
com.google.android.apps.muzei.util.LogoPaths.java
com.google.android.apps.muzei.util.MathUtil.java
com.google.android.apps.muzei.util.MultiSelectionController.java
com.google.android.apps.muzei.util.ObservableHorizontalScrollView.java
com.google.android.apps.muzei.util.PanScaleProxyView.java
com.google.android.apps.muzei.util.PanView.java
com.google.android.apps.muzei.util.ScrimUtil.java
com.google.android.apps.muzei.util.Scrollbar.java
com.google.android.apps.muzei.util.SelectionBuilder.java
com.google.android.apps.muzei.util.ShadowDipsTextView.java
com.google.android.apps.muzei.util.SvgPathParser.java
com.google.android.apps.muzei.util.TickingFloatAnimator.java
com.google.android.apps.muzei.util.TypefaceUtil.java
com.google.android.apps.muzei.util.Zoomer.java
net.rbgrn.android.glwallpaperservice.BaseConfigChooser.java
net.rbgrn.android.glwallpaperservice.GLWallpaperService.java