FileDocCategorySizeDatePackage
PersistentDataStore.javaAPI DocAndroid 5.1 API10224Thu Mar 12 22:22:42 GMT 2015com.android.server.tv

PersistentDataStore

public final class PersistentDataStore extends Object
Manages persistent state recorded by the TV input manager service as an XML file. This class is not thread-safe thus caller must acquire lock on the data store before accessing it. File format: <tv-input-manager-state> <blocked-ratings> <rating string="XXXX" /> </blocked-ratings> <parental-control enabled="YYYY" /> </tv-input-manager-state>

Fields Summary
private static final String
TAG
private final android.content.Context
mContext
private final android.os.Handler
mHandler
private final android.util.AtomicFile
mAtomicFile
private final List
mBlockedRatings
private boolean
mBlockedRatingsChanged
private boolean
mParentalControlsEnabled
private boolean
mParentalControlsEnabledChanged
private boolean
mLoaded
private final Runnable
mSaveRunnable
Runnable posted when the state needs to be saved. This is used to prevent unnecessary file operations when multiple settings change in rapid succession.
private static final String
TAG_TV_INPUT_MANAGER_STATE
private static final String
TAG_BLOCKED_RATINGS
private static final String
TAG_RATING
private static final String
TAG_PARENTAL_CONTROLS
private static final String
ATTR_STRING
private static final String
ATTR_ENABLED
Constructors Summary
public PersistentDataStore(android.content.Context context, int userId)


         
        mContext = context;
        File userDir = Environment.getUserSystemDirectory(userId);
        if (!userDir.exists()) {
            if (!userDir.mkdirs()) {
                throw new IllegalStateException("User dir cannot be created: " + userDir);
            }
        }
        mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml"));
    
Methods Summary
public voidaddBlockedRating(android.media.tv.TvContentRating rating)

        loadIfNeeded();
        if (rating != null && !mBlockedRatings.contains(rating)) {
            mBlockedRatings.add(rating);
            mBlockedRatingsChanged = true;
            postSave();
        }
    
private voidbroadcastChangesIfNeeded()

        if (mParentalControlsEnabledChanged) {
            mParentalControlsEnabledChanged = false;
            mContext.sendBroadcastAsUser(new Intent(
                    TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED), UserHandle.ALL);
        }
        if (mBlockedRatingsChanged) {
            mBlockedRatingsChanged = false;
            mContext.sendBroadcastAsUser(new Intent(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED),
                    UserHandle.ALL);
        }
    
private voidclearState()

        mBlockedRatings.clear();
        mParentalControlsEnabled = false;
    
public android.media.tv.TvContentRating[]getBlockedRatings()

        loadIfNeeded();
        return mBlockedRatings.toArray(new TvContentRating[mBlockedRatings.size()]);
    
public booleanisParentalControlsEnabled()

        loadIfNeeded();
        return mParentalControlsEnabled;
    
public booleanisRatingBlocked(android.media.tv.TvContentRating rating)

        loadIfNeeded();
        synchronized (mBlockedRatings) {
            for (TvContentRating blcokedRating : mBlockedRatings) {
                if (rating.contains(blcokedRating)) {
                    return true;
                }
            }
        }
        return false;
    
private voidload()

        clearState();

        final InputStream is;
        try {
            is = mAtomicFile.openRead();
        } catch (FileNotFoundException ex) {
            return;
        }

        XmlPullParser parser;
        try {
            parser = Xml.newPullParser();
            parser.setInput(new BufferedInputStream(is), null);
            loadFromXml(parser);
        } catch (IOException | XmlPullParserException ex) {
            Slog.w(TAG, "Failed to load tv input manager persistent store data.", ex);
            clearState();
        } finally {
            IoUtils.closeQuietly(is);
        }
    
private voidloadBlockedRatingsFromXml(org.xmlpull.v1.XmlPullParser parser)

        final int outerDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (parser.getName().equals(TAG_RATING)) {
                String ratingString = parser.getAttributeValue(null, ATTR_STRING);
                if (TextUtils.isEmpty(ratingString)) {
                    throw new XmlPullParserException(
                            "Missing " + ATTR_STRING + " attribute on " + TAG_RATING);
                }
                mBlockedRatings.add(TvContentRating.unflattenFromString(ratingString));
            }
        }
    
private voidloadFromXml(org.xmlpull.v1.XmlPullParser parser)


       
               
        XmlUtils.beginDocument(parser, TAG_TV_INPUT_MANAGER_STATE);
        final int outerDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (parser.getName().equals(TAG_BLOCKED_RATINGS)) {
                loadBlockedRatingsFromXml(parser);
            } else if (parser.getName().equals(TAG_PARENTAL_CONTROLS)) {
                String enabled = parser.getAttributeValue(null, ATTR_ENABLED);
                if (TextUtils.isEmpty(enabled)) {
                    throw new XmlPullParserException(
                            "Missing " + ATTR_ENABLED + " attribute on " + TAG_PARENTAL_CONTROLS);
                }
                mParentalControlsEnabled = Boolean.valueOf(enabled);
            }
        }
    
private voidloadIfNeeded()

        if (!mLoaded) {
            load();
            mLoaded = true;
        }
    
private voidpostSave()

        mHandler.removeCallbacks(mSaveRunnable);
        mHandler.post(mSaveRunnable);
    
public voidremoveBlockedRating(android.media.tv.TvContentRating rating)

        loadIfNeeded();
        if (rating != null && mBlockedRatings.contains(rating)) {
            mBlockedRatings.remove(rating);
            mBlockedRatingsChanged = true;
            postSave();
        }
    
private voidsave()


       
        final FileOutputStream os;
        try {
            os = mAtomicFile.startWrite();
            boolean success = false;
            try {
                XmlSerializer serializer = new FastXmlSerializer();
                serializer.setOutput(new BufferedOutputStream(os), "utf-8");
                saveToXml(serializer);
                serializer.flush();
                success = true;
            } finally {
                if (success) {
                    mAtomicFile.finishWrite(os);
                    broadcastChangesIfNeeded();
                } else {
                    mAtomicFile.failWrite(os);
                }
            }
        } catch (IOException ex) {
            Slog.w(TAG, "Failed to save tv input manager persistent store data.", ex);
        }
    
private voidsaveToXml(org.xmlpull.v1.XmlSerializer serializer)

        serializer.startDocument(null, true);
        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
        serializer.startTag(null, TAG_TV_INPUT_MANAGER_STATE);
        serializer.startTag(null, TAG_BLOCKED_RATINGS);
        synchronized (mBlockedRatings) {
            for (TvContentRating rating : mBlockedRatings) {
                serializer.startTag(null, TAG_RATING);
                serializer.attribute(null, ATTR_STRING, rating.flattenToString());
                serializer.endTag(null, TAG_RATING);
            }
        }
        serializer.endTag(null, TAG_BLOCKED_RATINGS);
        serializer.startTag(null, TAG_PARENTAL_CONTROLS);
        serializer.attribute(null, ATTR_ENABLED, Boolean.toString(mParentalControlsEnabled));
        serializer.endTag(null, TAG_PARENTAL_CONTROLS);
        serializer.endTag(null, TAG_TV_INPUT_MANAGER_STATE);
        serializer.endDocument();
    
public voidsetParentalControlsEnabled(boolean enabled)

        loadIfNeeded();
        if (mParentalControlsEnabled != enabled) {
            mParentalControlsEnabled = enabled;
            mParentalControlsEnabledChanged = true;
            postSave();
        }